1.1简介
wait
和notify
常见应用在线程通信中,例如经典的生产者消费者问题。
wait
阻塞当前线程。 notify
唤醒阻塞的线程(一个)。 notifyAll
唤醒阻塞的线程(全部)。
wait
和notify
要成对出现,如果不写在synchronized
中,在并发执行的情况下会出现程序执行混乱的情况。wait
和notify
保证的是线程的相对执行顺序,sychronized
保证的是原子性,可见性,有序性。两者相互配合使用可利用全局变量实现线程通信。
1.2论证
拿经典的生产者消费者为例:
package study;
public class Message {
//初始产品数量
private int capSize = 0;
//最大产品数量
private int maxSize = 20;
//生产消息
public synchronized void produceMsg() throws InterruptedException {
if(capSize < maxSize){
//消息未满,生产消息,唤醒消费者
capSize++;
System.out.println("produce remain num:"+capSize);
notifyAll();
}else{
//消息已满,阻塞生产者
System.out.println("produce alread is max");
wait();
}
}
//消费消息
public synchronized void consumeMsg() throws InterruptedException {
//无可消费消息,阻塞消费者
if(capSize <=0){
notifyAll();
}else{
//有可消费消息,消费消息
capSize--;
System.out.println("consume remain num:"+capSize);
}
}
}
假设,wait
和notify
不必写在sychronized
代码块中
如果去除sychronized关键字
,当前商品数量为19时,两个生产者线程同时生产商品,即执行capSize++
,因为没有并发控制,结果可能为20,出现了数据丢失的情况。以此可以证明 wait
和notify
必须在synchronized
代码块中出现