线程-004-线程间的协作及状态迁移
2018-02-26 16:37
316 查看
状态迁移图
常言道,一图胜千言。线程协作
我们前面讲到使用synchronized进行线程间的互斥。
但,如果我们需要更加精确地控制。比如:
如果空间为空则写入,如果非空则一直等待。
空间已经为空时,“通知”其他等待的线程。
为此,JDK 为我们准备了
wait()、
notify()、
notifyAll()等方法,用于线程的控制。
等待队列
所有的实例都拥有一个等待队列(这是一个虚拟的概念)。可以理解为这是为每个实例准备的休息室。在执行
wait()之后,线程便会停下手中的事情,进入这个休息室休息。
在遇到以下的情况,才会退出等待:
wait()方法超时
其他线程的
notify()/
notifyAll()/
interrupt()方法来唤醒线程
wait
wait()让线程进入等待队列。
object
假设执行如下语句:object.wait();
则当前线程会停止,并且进入实例 object 的等待队列中。称之为,线程正在 object 上等待。
this
若实例化方法中有以下语句:wait(); //(1) this.wait(); //(2)
(1) (2) 两句的效果是相同的。执行了
wait()的线程将会进入 this 的等待队列。称之为,线程正在 this 上等待。
图解
若要执行wait(),则线程必须持有锁。若线程进入等待队列,则会释放实例持有的锁。
notify
notify()会将等待队列中的一个线程取出。
object.notify()
上面的代码,会将 object 的等待队列中唤醒,然后退出等待队列。
图解
整体流程如下:注意
当执行
notify()方法的时候,如果等待队列中的线程不止一个,则接下来优先选择哪一个是没有明文规定的,取决于 Java 运行环境。
所以,很多人推荐使用
notifyAll()
notifyAll
notifyAll()从等待队列中取出所有线程。
object
假设执行如下语句:object.notifyAll();
则当 object 实例的等待队列中休眠的所有线程都会被唤醒。
this
若实例化方法中有以下语句:notifyAll(); //(1) this.notifyAll(); //(2)
(1) (2) 两句的效果是相同的。执行该语句所在的实例 (this) 等待队列中的所有线程都将退出等待队列。
图解
总结
上述的几个方法线程调用时都要求持有锁,如果不满足,则会抛出异常java.lang.IlleagalMonitorStateException。
相关内容
线程-001-线程简介线程-002-基本的线程机制
线程-003-线程的同步与锁
线程-004-线程间的协作及状态迁移
相关文章推荐
- 线程状态的迁移
- java线程状态迁移 - <图解java多线程设计模式> 笔记
- Java多线程之线程的状态以及线程间协作通信导致的线程状态转换
- Java 并发:线程间通信与协作
- java线程停止、暂停和恢复等状态的控制
- 《Java高并发程序设计》学习 --3.1多线程的团队协作:同步控制
- 用观查者模式传递线程状态
- 线程的状态
- 线程状态
- Openstack卷迁移状态图
- UML实践---用例图、顺序图、状态图、类图、包图、协作图
- 线程状态与tcb、线程的生命周期
- 1.1.2获取和控制线程状态(Getting and Seeting Thread State)
- java 获取线程状态 判断线程是否已启动(未测试)
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
- 线程的基本概念、线程的基本状态以及状态之间的关系
- 为什么要将线程设置成分离状态
- java多线程之线程状态
- UML实践详细经典教程----用例图、顺序图、状态图、类图、包图、协作图
- 线程的几种状态转换<转>