Java多线程之wait(),notify(),notifyAll()
wait():
等待对象的同步锁,须要获得该对象的同步锁才干够调用这种方法,否则编译能够通过,但执行时会收到一个异常:IllegalMonitorStateExcep
调用随意对象的 wait() 方法导致该线程堵塞,该线程不可继续运行,而且该对象上的锁被释放。
notify():
唤醒在等待该对象同步锁的线程(仅仅唤醒一个,假设有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,并且不是按优先级。
调用随意对象的notify()方法则导致因调用该对象的 wait()方法而堵塞的线程中随机选择的一个解除堵塞(但要等到获得锁后才真正可运行)。
notifyAll():
唤醒全部等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。
通常,多线程之间须要协调工作:假设条件不满足,则等待;当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。
比如:
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
在还有一线程B中,假设B更改了某些条件,使得线程A的condition条件满足了,就能够唤醒线程A :
synchronized(obj) {
condition = true;
obj.notify();
}
须要注意的概念是:
# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj){...} 代码段内。
# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj){...} 代码段内唤醒A。
# 当obj.wait()方法返回后,线程A须要再次获得obj锁,才干继续运行。
#假设A1,A2,A3都在obj.wait(),则B调用obj.notify()仅仅能唤醒A1,A2,A3中的一个(详细哪一个由JVM决定)。
#obj.notifyAll()则能所有唤醒A1,A2,A3,可是要继续运行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3仅仅有一个有机会获得锁继续运行,比如A1,其余的须要等待A1释放obj锁之后才干继续运行。
# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,可是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续运行。
谈一下synchronized和wait()、notify()等的关系:
1.有synchronized的地方不一定有wait,notify
2.有wait,notify的地方必有synchronized.这是由于wait和notify不是属于线程类,而是每个对象都具有的方法,并且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。
另外,注意一点:假设要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,由于假设调用完wait,该线程就已经不是currentthread了。相关文章
- Jmeter里的全能java测试sampler - Java request
- java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提
- Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
- java多线程执行问题
- Java魔法堂:内部类详解
- Java实现 蓝桥杯VIP 算法提高 研究兔子的土豪
- Java实现蓝桥杯模拟带九9的数的个数
- Java实现第九届蓝桥杯螺旋折线
- java struts2入门学习--OGNL语言基本用法
- 用Java来写常见的排序算法
- 【JAVA】 03-Java中的异常和包的使用
- java多线程提高性能写法
- Java多线程--让主线程等待所有子线程执行完毕
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
- 零基础学java-1,课程目录
- Java微服务篇5——Docker
- Java — java.lang.NullPointerException - 如何处理空指针异常
- 常见java面试题 普通类和抽象类的区别?
- 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略
- Java List详解
- java多线程使用mdc追踪日志
- Java Thread 多线程 介绍
- Java中的字符流与字节流