您的位置:首页 > 编程语言 > Java开发

线程-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 thread