Java线程状态转换,WAITING到BLOCKED还是RUNNABLE?

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

  • 等待永远不会直接进入RUNNABLE
  • 该线程正在等待直到通知……然后它变为 BLOCKED …
  • 一旦通知此线程,它将无法运行 …这是 …阻塞状态。

因此,对SO的一致意见是:在调用notify()notifyAll()之后,线程从WAITING转换为BLOCKED ; 下图说明了绿色的这种转变。

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

在此处输入图像描述

任何显示将WAITING中的线程带到RUNNABLE的notify调用的图表都是错误的(或使用未明确的快捷方式)。 一旦线程从notify唤醒(甚至从虚假的唤醒中唤醒),它需要重新锁定它正在等待的对象的监视器。 这是BLOCKED状态。

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

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

在当前线程放弃对该对象的锁定之前,唤醒的线程将无法继续。

Object#wait()

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

我最近关注这个问题。

正如Oracle文档Thread.State所说,我们可以使用LockSupport.park()将当前线程置于’WAITING’或’TIMED_WAITING’状态。

所以当你尝试LockSupport.unpark()时 ,指定的线程将从’WAITING’/’TIMED_WAITING’返回’RUNNABLE’。 (我不确定它是否会通过’BLOCKED’状态)

线程处于WAITING状态进入BLOCK状态,直到它通过notify获取监视器并变为RUNNABLE

同样适用于TIMEDWAITING ,它处于BLOCK状态,如果监视器由某个其他线程保持,即使已经过了指定的时间。 (您的图表需要更正)