在java中当需要实现同步的时候使用synchronized(对象实例){}
synchronized(对象实例){}的作用:是获取一个对象锁
wait(),notify()只能放在 synchronized里面使用否则会报java.lang.IllegalMonitorStateException异常;
wait()作用:释放掉得到的对象锁(释放cpu资源)后面的代码不会执行了,等待唤醒后才会执行,如果当前线程休眠(阻塞)。而没有被唤醒,会一直等待。
notify()作用:通知并唤醒休眠(阻塞)的线程。此线程不一定立刻执行(如果还有别的线程跟他抢资源的话)并且当前的线程不会释放对象锁会继续执行,当执行完当前的代码以后才会去执行别的线程。
Thread.sleep()作用:主动释放cpu资源(用在一些多线程循序执行上);
如 建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。这个问题用Object的wait(),notify()就可以很方便的解决。代码如下
public class Main implements Runnable {
//需要打印的字段
private String name;
//上一个对象
private Object prev;
//当前对象
private Object self;
private Main(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
//循环次数
int count = 10;
while (count > 0) {
//获取上一次对象的对象锁
synchronized (prev) {
//获取当前对象的对象锁
synchronized (self) {
//打印
System.out.print(name);
//重置条件
count--;
try {
//释放cpu资源
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//通知当前对象醒来
self.notify();
}
try {
//上一个对象释放锁并休眠
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
Main pa = new Main("A", c, a);
Main pb = new Main("B", a, b);
Main pc = new Main("C", b, c);
new Thread(pa).start();
Thread.sleep(1);
new Thread(pb).start();
Thread.sleep(1);
new Thread(pc).start();
}
}