JAVA线程同步中wait()和notify()简洁例子
JAVA线程同步中wait()和notify()简洁例子
搞懂这两个的用法之前,请你务必搞懂线程同步的道理,否则,下面这一大篇你应该是看不懂的。
wait()和notify()一系列的方法,是属于对象的,不是属于线程的。它们用在线程同步时,synchronized语句块中。
我们都知道,在synchronized语句块中,同一个对象,一个线程在执行完这一块代码之前,另一个线程,如果传进来的是同一个object,是不能进入这个语句块的。也就是说,同一个对象
是不能同时被两个线程用来进入synchronized中的。这就是线程同步。
废话不多说,先用通俗一点的语言来解释一下wait()和notify():
wait()意思是说,我等会儿再用这把锁,CPU也让给你们,我先休息一会儿!
notify()意思是说,我用完了,你们谁用?
也就是说,wait()会让出对象锁,同时,当前线程休眠,等待被唤醒,如果不被唤醒,就一直等在那儿。
notify()并不会让当前线程休眠,但会唤醒休眠的线程。
先看第一个例子!
public class ThreadF {
public static void main(String[] args) {
final Object object = new Object();
Thread t1 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T1 start!");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T1 end!");
}
}
};
Thread t2 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T2 start!");
object.notify();
System.out.println("T2 end!");
}
}
};
t1.start();
t2.start();
}
}
这第一个例子很简单,写了两个线程(分别是两个类,两个run方法)。
两个run方法之间没有关系,但是,他们都用了同一个object!
仔细看,T1里面主要写了个wait(),而T2里面主要写了个notify()。
我们看到执行结果是:
T1 start!
T2 start!
T2 end!
T1 end!
流程可以这样解释:
T1启动,让出锁,让出CPU,T2获得CPU,启动,唤醒使用了object的休眠的线程,T1被唤醒后等待启动,T2继续执行,T2执行完,T1获得CPU后继续执行。
值得一提的是,再强调一遍:
wait会让出CPU而notif
y不会,notify重在于通知使用object的对象“我用完了!”,wait重在通知其它同用一个object的线程“我暂时不用了”并且让出CPUT。
所以说,看上面的顺序,
T2 start!
T2 end!
是连续的,说明它并没有因调用了notify而暂停!
那么,如
果两个线程都写wait没有线程写notify会有什么现象呢?试一下就知道了。
结果是,
T1 start!
T2 start!
然后就是一直等待!
道理很显然,T1先启动,然后wait了,T2获得了锁和CPU,在没有其它线程与它竞争的情况下,T2执行了,然后也wait了。
在这里,两个线程都在等待,没有其它线程将它们notify,所以结果就是无休止地等下去!
至少说明了一点,wait后如果没有其它线程将它notify,是绝不可能重新启动的。不可能因为目前没有线程占用CPU,某一个正在等待的线程就自动重启。
下面,我再把它改一下,写四个线程,分别是
T1 wait()
T2 notify()
T3 notify()
T4 wait()
public class ThreadF {
public static void main(String[] args) {
final Object object = new Object();
Thread t1 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T1 start!");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T1 end!");
}
}
};
Thread t2 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T2 start!");
object.notify();
System.out.println("T2 end!");
}
}
};
Thread t3 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T3 start!");
object.notify();
System.out.println("T3 end!");
}
}
};
Thread t4 = new Thread() {
public void run()
{
synchronized (object) {
System.out.println("T4 start!");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T4 end!");
}
}
};
t1.start();
t2.start();
t3.start();
t4.start();
}
}
首先,大家知道,线程启动的顺序,和代码的先后顺序,理论上是没有关系的!
比如我这儿写的是按T1-T2-T3-T4的先后顺序先后start(),但实际上谁先启动,是
有一定几率的。
执行上面代码,有两种结果:
一种是刚好wait两次,notify两次,notify在wait之后执行,刚好执行完。
另一种是,也是刚好wait两次,notify两次,但是,notify在wait之前执行,于是,至少会有一个线程由于后面没有线程将它notify而无休止
地等待下去!
我摘选了两种情况的输出结果,仅供参考:
1、可以执行结束的情况:
T1 start!
T2 start!
T2 end!
T1 end!
T4 start!
T3 start!
T3 end!
T4 end!
执行流程是:
T1启动,wait,T2获得锁和CPU,T2宣布锁用完了其它线程可以用了,然后继续执行,T2执行完,T1被刚才T2唤醒后,等待T2执行完后,抢到了CPU,T1执行,
T1执行完,T4获得CPU,启动,wait,T3获得了锁和CPU,执行,宣布锁用完了,其它线程可以用了,然后继续执行,T3执行完,已经被唤醒并且等待已久的T4
得到CPU,执行。
2、不能执行结束,有线程由于没有其它线程唤醒,一直在等待中:
T1 start!
T2 start!
T2 end!
T1 end!
T3 start!
T3 end!
T4 start!
执行流程:
T1启动,wait,让出CPU和锁,T2得以启动。T2启动,并唤醒一个线程,自己继续执行。被唤醒的线程,也就是T1等待启动机会。
T2执行完,T1抢到了CPU,执行,并结束。
这时,只剩下T3和T4,在此时,两个线程的机会均等。
但是,T3抢到了CPU,于是它执行了,而且唤醒了线程,虽然此时并没有线程休眠。说白了,它浪费了一次notify。T3顺利执行完。
这时,终于轮到了T4,它启动了,wait了,但是,后面已经没有线程了,它的wait永远不会有线程帮它notify了!
于是,它就这么等着!
请仔细看执行流程,看懂,再自己做一下试验。
仔看看,你会看到,凡是当前线程的run方法里面写了notify,有了start马上就会end,而如果是写的wait,有
…… 此处隐藏:2372字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [求职职场]加法运算定律的运用练习题
- [求职职场]大型石油化工工业过程节能新技术
- [求职职场]2015-2020年中国箱纸板行业分析与投资
- [求职职场]NADEX-IWC5A点焊机故障代码
- [求职职场]英语阅读 非常有用
- [求职职场]鲁卫疾控发〔2012〕2号(联合,印发山东
- [求职职场]2014年莆田公务员行测技巧:数字推理的
- [求职职场]基于最近发展区理论的高中数学课堂有效
- [求职职场]与贸易有关的知识产权协议
- [求职职场]【王风范】微演说·职场演说三
- [求职职场]新时代国珍健康大课堂
- [求职职场]群论期末考试复习题
- [求职职场]施工现场消防安全专项施工方案(范本)-
- [求职职场]初中物理光学知识点归纳完美版
- [求职职场]毕业设计总结与体会范文
- [求职职场]江南大学2018年上半年展示设计第1阶段
- [求职职场]景尚乡民兵参战支前保障方案
- [求职职场]【优质】2019年工会职工之家建设工作总
- [求职职场]数据库技术与应用—SQL Server 2008(第
- [求职职场]汽车变速箱构造与工作原理
- 首钢工业区工业遗产资源保护与再利用研
- 第4课 《大学》节选
- 2016程序文件——检验检测结果发布程序
- 2011年高考试题文言文阅读全解释__2011
- 化学是一门基础的自然科学
- 海外做市商制度的借鉴意义
- 外国建筑史复习资料(
- 七年级下思想品德期末综合测试(二)
- 思政课部2013年上学期教学工作总结
- 电大国际公法任务3 0004
- 《圆的认识》教学设计
- 中国轨道交通牵引变流器行业市场发展调
- 中泰证券#定期报告:坚守时代硬科技和
- 浅论企业财务管理与企业经营投资风险的
- 大功率半导体激光器光纤耦合技术调研报
- 中国传统家具的现状与发展探讨
- Broadcom数字电视芯片助海尔扩展高清电
- 新HSK4词汇练习 超全(五)
- 2013届高考数学单元考点复习12
- 雨霖铃精品课件




