生产者消费者多线程一个例子中while和notifyall的作用

代码如下

public synchronized void put(Object o) {  
          while (buf.size()==MAX_SIZE) {  
              wait(); // 如果buffer为full,就会执行wait方法等待(为了简单,我们省略try/catch语句块)  
          }  
          buf.add(o);  
          notify(); // 通知所有正在等待对象锁的Producer和Consumer(译者注:包括被阻挡在方法外的Producer和Consumer)  
     }  
        
     // Y: 这里是C2试图获取锁的地方(原作者将这个方法放到了get方法里面,此处,我把它放在了方法的外面)  
     public synchronized Object get() {  
          while (buf.size()==0) {  
              wait(); // 如果buffer为Null,就会执行wait方法(为了简单,同样省略try/catch语句块)  
              // X: 这里是C1试图重新获得锁的地方(看下面代码)  
          }  
          Object o = buf.remove(0);  
          notify(); // 通知所有正在等待对象锁的Producer和Consumer(译者注:包括被阻挡在方法外的Producer和Consumer)  
          return o;  
     }

 这里如果不用while用if会出现什么情况呢:(生产者P,消费者C)

1.buf.size() == 0时,C1进入,if判断为真,wait(抛出锁);C2在外等待

2.P1获得锁,add后buf == 1,唤醒C1

3.被唤醒的C1和C2抢锁,C2获得锁执行remove,此时buf.size()==0

4.C1此时获得锁,继续往下执行buf.remove但是此时buf.size()==0,抛出IndexArrayOutOfBoundsException

 

这里使用while判断就能避免此问题

 

 

这里使用notify会有什么问题呢,情景如下:(max_size == 1)

1.P1执行

2.P2,P3想put但是buf.size()==1 两个都wait

3.C1,C2同时想get,C1获得锁,get完buf.size()==0 并唤醒P2

4.C2,P2抢锁C2抢得,wait

5.P2获得锁Put后,buf.size()==1 唤醒P3

6.P3获得锁 wait 此时C2和P3同时wait,没有线程能notify了

 

如果使用notifyall可避免这种情况

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值