例如常见的生产者 - 消费者 模式:一边生产,一边消费。需要线程之间的通信,就可以利用wait / notify方法来实现。
object.wait() 和 object.notify()
wait的作用:1、实现线程的阻塞;2、会释放当前的同步锁
notify的作用:唤醒一个被阻塞的线程;
notifyAll的作用:唤醒所有被阻塞的线程,再去重新竞争。
代码demo:
/**
* @description:线程A
* @author: annecheng,2019-07-28 20:06
*/
public class ThreadA extends Thread{
private Object lock;
public ThreadA(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("start ThreadA");
try {
lock.wait(); // 实现线程的阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end ThreadA");
}
}
}
/**
* @description:线程B
* @author: annecheng,2019-07-28 20:06
*/
public class ThreadB extends Thread{
private Object lock;
public ThreadB(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("start ThreadB");
lock.notify(); //唤醒阻塞的线程
System.out.println("end ThreadB");
}
}
}
/**
* @description:测试
* @author: annecheng,2019-07-28 20:09
*/
public class WaitNotifyDemo {
public static void main(String[] args) {
Object lock = new Object();
ThreadA threadA = new ThreadA(lock);
threadA.start();
ThreadB threadB = new ThreadB(lock);
threadB.start();
}
}
分析运行过程:
1、 使用lock.wait()为何要用synchronized加锁?
答:第一,object.wait()底层规定了如果不加锁,会抛异常。如果当前的线程不是获得了对象锁的线程,会抛出IllegalMonitorStateException异常。
第二,线程A和线程B之间的通信需要依赖一个共同的东西,去维持通信的管道,这里就是同步锁(synchronized)。
2、wait和sleep的区别?
wait会释放锁资源,并且释放cpu资源,而sleep会释放CPU资源,但是不会释放锁资源。