`
unique5945
  • 浏览: 131885 次
  • 来自: 杭州
社区版块
存档分类
最新评论

关于notify和notifyAll的讨论

    博客分类:
  • JAVA
阅读更多
关于notify和notifyAll的讨论,很有意义,记录下来,写了些自己的心得:对notify notifyAll有疑问的可以参考下这篇讨论http://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again
很多文章建议使用notifyAll比notfiy安全,但这里的几个回答详细分析了两个方法的适用场景。notifyAll虽然可以唤醒所有处于WAITING(不消耗CPU)的状态的线程,但被唤醒的线程如果依次被执行后马上去争抢锁,就会有大量的线程进入到BLOCKED状态,增加CPU的开销。此时用notify反而更好。第5个解释我觉得比较到位:
1)notify适用于所有等待的线程都是对等的(或者说唤醒顺序对其执行任务无影响),或者适用于本来就只有一个等待线程的场景。不过文中的例子觉得不妥,一般线程池都是设计成可并行执行的,如果只是串行执行就没意义了。应该如第7个解释中说的,适用于资源池,即任意数量的消费者都要从池中获取资源,但一次只能有一个获取到这个资源。可以将生产者消费者的例子修改下,假设消费者和生产者是两个对象,而消费者的get方法里有同步块(代码如下):
public Object get() {
synchronized(lock){//lock可以是所有消费者在执行get时要获取的公共锁
    while (buf.size()==0) {
        wait();
    }
    Object o = buf.remove(0);
    notify();
    return o;
    }
}
则这样用notify就比较合适,只唤醒其它等待的消费者线程中的一个,此处如果改成notfiyAll的话就让其它线程被唤醒后立刻进入BLOCKED状态,增加了CPU的开销。
2)notfiyAll适用于等待的线程有不同的目标,可以并行执行的场景。这样才不至于使所有线程被唤醒后又进入到BLOCKED状态。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics