synchronized关键字
synchronized关键字解决的是多个线程访问资源的同步性,synchronized关键字可以保证被它修饰的方法或代码块在任意时刻只能有一个线程执行。
案例:
public class demo2 {
public static void main(String[] args) throws InterruptedException {
//格式: synchronized(锁对象){
//
//}
Runnable run = new Ticket();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
static class Ticket implements Runnable {
private int count = 10;
private Object o = new Object();
@Override
public void run() {
while (true) {
synchronized (o) {
if (count > 0) {
//买票
System.out.println(Thread.currentThread().getName() + "正在准备买票");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("出票成功,余票:" + count);
}else{
break;
}
}
}
}
}
}
public class demo2 {
public static void main(String[] args) throws InterruptedException {
//同步方法
//格式: public synchronized 方法名(){}
Runnable run = new Ticket();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
static class Ticket implements Runnable {
private int count = 10;
private Object o = new Object();
@Override
public void run() {
while (true) {
boolean flag = sale();//封装成方法
if (!flag) {
break;
}
}
}
public synchronized boolean sale() {
if (count > 0) {
//买票
System.out.println(Thread.currentThread().getName() + "正在准备买票");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("出票成功,余票:" + count);
return true;
}
return false;
}
}
}
//
Thread-0正在准备买票
出票成功,余票:9
Thread-2正在准备买票
出票成功,余票:8
Thread-2正在准备买票
出票成功,余票:7
Thread-2正在准备买票
出票成功,余票:6
Thread-2正在准备买票
出票成功,余票:5
Thread-2正在准备买票
出票成功,余票:4
Thread-2正在准备买票
出票成功,余票:3
Thread-2正在准备买票
出票成功,余票:2
Thread-2正在准备买票
出票成功,余票:1
Thread-2正在准备买票
出票成功,余票:0
多个线程运行时,在synchronized修饰的代码块或方法里哪个线程先抢到就先运行(非公平锁),且这个时刻只有这个线程执行这段代码,另一个线程受阻,必须等待当前线程执行完这个代码后才能执行该代码,线程与线程之间是互斥的,因为在执行synchronized代码块时会锁定当前对象,只有执行完改代码才能释放该对象锁,下一个线程才能执行并锁定该对象。
可以修饰的对象:
- 修饰一个代码块
- synchronized(锁对象){ }
- 修饰一个方法
- public synchronized void method(){ }
- 修饰一个静态的方法
- public synchronized static void method(){ }//静态方法是属于类的而不是对象的,同理,synchronized修饰的静态方法锁定的是这个类的所有对象
- 修饰一个类
- synchronized(ClassName.class){ }//synchronized作用是给这个类加锁,类的所有对象用的是同一把锁。