【无标题】

wait和notify为什么必须写在synchronized代码块中

1.1简介

waitnotify 常见应用在线程通信中,例如经典的生产者消费者问题。

wait阻塞当前线程。 notify唤醒阻塞的线程(一个)。 notifyAll唤醒阻塞的线程(全部)。

waitnotify要成对出现,如果不写在synchronized中,在并发执行的情况下会出现程序执行混乱的情况。waitnotify保证的是线程的相对执行顺序,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);
        } 
    }
}

假设,waitnotify不必写在sychronized代码块中

如果去除sychronized关键字,当前商品数量为19时,两个生产者线程同时生产商品,即执行capSize++,因为没有并发控制,结果可能为20,出现了数据丢失的情况。以此可以证明 waitnotify必须在synchronized代码块中出现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值