转载:用实例揭示notify()和notifyAll()的本质区别 收藏
来源:互联网 发布:美国亚马逊年销售数据 编辑:程序博客网 时间:2024/06/07 06:27
转载:用实例揭示notify()和notifyAll()的本质区别 收藏
转自:http://www.cnblogs.com/armyao/archive/2010/12/27/1917989.html
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/SuperMiner/archive/2007/04/22/1574615.aspx
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。
两者的最大区别在于:
- notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
- notify则文明得多,它只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们。当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
下面是一个很好的例子:
import java.util.*;class Widget {}class WidgetMaker extends Thread { List<Widget> finishedWidgets = new ArrayList<Widget>(); public void run() { try { while(true) { Thread.sleep(5000); // 需要5秒钟才能新产生一个Widget Widget w = new Widget(); /* * * 如果用notifyAll,则所有线程都企图冲出wait状态,第一个线程得到了锁,并取走了Widget,由于要间隔5秒针才new一个新的Widget,此时还没有新的Widget产生 * 并且解开了锁,然后第二个线程获得锁,运行finishedWidgets.remove(0), * 但是由于finishedWidgets现在还是空的,于是产生异常 * * ***********这就是为什么下面的那一句不能用notifyAll而是要用notify */ synchronized(finishedWidgets) { finishedWidgets.add(w); finishedWidgets.notify(); //这里只能是notify而不能是notifyAll } } } catch(InterruptedException e) { } } public Widget waitForWidget() { synchronized(finishedWidgets) { if(finishedWidgets.size()==0) { try { finishedWidgets.wait(); }catch(InterruptedException e){ } } return finishedWidgets.remove(0); } }}public class WidgetUser extends Thread { private WidgetMaker maker; public WidgetUser(String name,WidgetMaker maker) { super(name); this.maker = maker; } public void run() { Widget w = maker.waitForWidget(); System.out.println(getName()+" got a widget"); } public static void main(String[] args) { WidgetMaker maker=new WidgetMaker(); maker.start(); new WidgetUser("Lenny",maker).start(); new WidgetUser("Moe",maker).start(); new WidgetUser("Curly",maker).start(); }}
总结一下:
notifyAll(),使线程退出wait状态,变成等待该对象上的锁
notify只选择一个wait状态线程进行通知,并使它获得该对象上的锁,其他等待线程继续处在wait状态
阅读全文
0 0
- 转载:用实例揭示notify()和notifyAll()的本质区别 收藏
- 用实例揭示notify()和notifyAll()的本质区别
- 用实例揭示notify()和notifyAll()的本质区别
- 用实例揭示notify()和notifyAll()的本质区别
- 用实例揭示notify()和notifyAll()的本质区别
- Java—用实例揭示notify()和notifyAll()的本质区别
- notify()和notifyAll() 本质区别 --- 示例 (转)
- notify() 和 notifyAll() 的区别
- notify和notifyAll的区别
- notify()和notifyAll()的区别
- notify()和notifyAll()的区别
- notify() 和notifyAll()区别
- notify和notifyAll区别
- notify()和notifyAll()区别
- notify和notifyAll的区别和相同
- notify()和notifyAll()的区别---小笔记
- java中notify()和notifyall的区别
- java notify和notifyAll的区别
- 关于过滤器,拦截器,监听器具体应用上的区别
- python 代理
- Java静态绑定与动态绑定
- yii2.0 常用的操作
- 自定义控件和自定义属性的总结
- 转载:用实例揭示notify()和notifyAll()的本质区别 收藏
- SpringBoot应用与原理之项目打包方案
- cookie 和session 的区别详解
- 关于分布式事务、两阶段提交协议、三阶提交协议
- 图像处理中的卷积和滤波详解
- quartz异常
- 0到n-1排成一个环,从数字0开始数,删除第m个数字,球最后的一个数。
- codeves 2980 买帽子 字符串dp
- ibatis insert 数组