Java 线程状态转换、等待阻塞还是运行?

SO共识与互联网上几乎所有Java线程状态图之间似乎存在差异;具体来说,关于线程状态从调用后或被调用后转换...WAITINGnotify()notifyAll()

因此,SO 上的一致性是:线程在调用或 ;下图以绿色说明了此转换。WAITINGBLOCKEDnotify()notifyAll()

问题

为什么网络上的大多数状态图都说明了从 到 的过渡,而不是?红色描绘显示不正确的过渡;我错过了什么吗?WAITINGRUNNABLEBLOCKED

enter image description here


答案 1

任何显示将线程从等待引入 RUNNABLE 的调用的图都是错误的(或者正在使用未澄清的快捷方式)。一旦线程从(甚至从虚假唤醒)中被唤醒,它需要重新锁定它正在等待的对象的监视器。这是“已阻止”状态。notifynotify

等待监视器锁定的线程被阻止的线程状态。处于阻塞状态的线程正在等待监视器锁进入同步的块/方法或在调用 后重新输入同步的块/方法。Object.wait

这在 Object#notify() 的 javadoc 中进行了解释:

唤醒的线程将无法继续,直到当前线程放弃此对象上的锁定。

Object#wait()

然后,线程将等待,直到它可以重新获得监视器的所有权并恢复执行。


答案 2

处于等待状态的线程进入阻塞状态,直到它通过通知获取监视器并成为RUNNABLE

这同样适用于TIMEDWAITING,如果监视器被其他线程持有,即使指定的时间已过去,它也处于BLOCK状态。(您的图表需要更正)