SO共识和网上几乎所有的Java线程状态图似乎都有出入;具体来说,关于从 WAITING之后notify()或被notifyAll()调用的线程状态转换......
所以对 SO 的共识是:一个线程在调用or后从WAITING到; 下图以绿色说明了这种转变。BLOCKEDnotify()notifyAll()
问题
为什么网络上的大多数状态图都说明了从WAITING到的转换RUNNABLE,而不是BLOCKED?红色表示不正确的过渡;我错过了什么吗?

SO共识和网上几乎所有的Java线程状态图似乎都有出入;具体来说,关于从 WAITING之后notify()或被notifyAll()调用的线程状态转换......
所以对 SO 的共识是:一个线程在调用or后从WAITING到; 下图以绿色说明了这种转变。BLOCKEDnotify()notifyAll()
为什么网络上的大多数状态图都说明了从WAITING到的转换RUNNABLE,而不是BLOCKED?红色表示不正确的过渡;我错过了什么吗?

任何显示notify将线程从 WAITING 变为 RUNNABLE 的调用的图表都是错误的(或使用了未明确的快捷方式)。一旦线程从notify(甚至是虚假唤醒)中唤醒,它需要重新锁定它正在等待的对象的监视器。这就是BLOCKED状态。
线程阻塞等待监视器锁的线程状态。处于阻塞状态的线程正在等待监视器锁进入同步块/方法或调用后重新进入同步块/方法
Object.wait。
这在以下的 javadoc 中进行了解释Object#notify():
在当前线程放弃对该对象的锁定之前,被唤醒的线程将无法继续。
然后线程等待直到它可以重新获得监视器的所有权并恢复执行。
处于WAITING状态的线程进入BLOCK状态,直到它通过 notify 获得监视器并变为RUNNABLE。
同样适用于TIMEDWAITING,它进入BLOCK状态,如果监视器被其他线程持有,即使指定的时间已经过去。(您的图表需要更正)
我最近专注于这个问题。
正如 Oracle 文档Thread.State所说,我们可以使用 LockSupport.park() 将当前线程置于“WAITING”或“TIMED_WAITING”状态。
所以当你尝试LockSupport.unpark()时,指定的线程将从'WAITING'/'TIMED_WAITING'返回到'RUNNABLE'。(我不确定它是否会进入“BLOCKED”状态)
值得一提的是,Thread.interrupt()method during WAITINGstate while in lock.wait()method 也是如此。
Thread.interrupt()方法首先将标志设置为true的WAITING线程BLOCKED,isInterrupted只有在重新获得锁之后,被中断的线程才能抛出InterruptedException(很明显,因为它无法处理异常,所以在没有排他锁的情况下继续执行)。(此处为示例)
简单的说
总是WAITING -> BLOCKED能够再次竞争锁,然后最终获得它并运行它的代码RUNNABLE。