Java 线程状态转换,WAITING 到 BLOCKED,还是 RUNNABLE?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28378592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java thread state transition, WAITING to BLOCKED, or RUNNABLE?
提问by raffian
There seems to be a discrepancy between SO consensus and nearly every Java thread state diagram on the Internet; specifically, regarding thread state transition fromWAITING
after notify()
or notifyAll()
is invoked...
SO共识和网上几乎每个Java线程状态图似乎都存在差异;具体来说,关于从WAITING
之后notify()
或被notifyAll()
调用的线程状态转换......
- WAITING nevergoes directly to RUNNABLE
- The thread is WAITING until it is notified...Then it becomesBLOCKED...
- Once this thread is notified, it will not be runnable...This is..Blocked State.
So the concensus on SO is: a thread transitions from WAITING
to BLOCKED
after invoking notify()
or notifyAll()
; diagram below illustrates this transition in green.
所以对 SO 的共识是:在调用or之后线程从WAITING
到;下图以绿色说明了这种转变。BLOCKED
notify()
notifyAll()
Question
问题
Why do most state diagrams on the webillustrate the transition from WAITING
to RUNNABLE
, not BLOCKED
? Depiction in red shows the incorrect transition; am I missing something?
为什么网络上的大多数状态图都说明了从WAITING
到的转换RUNNABLE
,而不是BLOCKED
?红色描述显示了不正确的过渡;我错过了什么吗?
采纳答案by Sotirios Delimanolis
Any diagram that shows a notify
invocation bringing a thread from WAITING to RUNNABLE is wrong (or is using an unclarified shortcut). Once a thread gets awoken from a notify
(or even from a spurious wakeup) it needs to relock the monitor of the object on which it was waiting. This is the BLOCKED
state.
任何显示notify
将线程从 WAITING 带到 RUNNABLE的调用的图表都是错误的(或使用了未阐明的快捷方式)。一旦线程从notify
(甚至从虚假唤醒)中唤醒,它需要重新锁定它正在等待的对象的监视器。这就是BLOCKED
状态。
Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling
Object.wait
.
线程阻塞等待监视器锁的线程状态。处于阻塞状态的线程正在等待监视器锁进入同步块/方法或调用后重新进入同步块/方法
Object.wait
。
This is explained in the javadoc of Object#notify()
:
这在以下的 javadoc 中有解释Object#notify()
:
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object.
被唤醒的线程将无法继续,直到当前线程放弃对该对象的锁定。
and Object#wait()
The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
然后线程等待直到它可以重新获得监视器的所有权并恢复执行。
回答by Sotirios Delimanolis
A thread is in WAITINGstate goes in BLOCKstate,until it acquires monitor by notify and become RUNNABLE.
处于WAITING状态的线程进入BLOCK状态,直到它通过 notify 获取监视器并变为RUNNABLE。
Same applies for TIMEDWAITING,it goes in BLOCKstate,if monitor is hold by some other thread,even though specified time has passed.(your diagram need to be corrected)
同样适用于TIMEDWAITING,它进入BLOCK状态,如果监视器被其他线程保持,即使指定的时间已经过去。(您的图表需要更正)
回答by hgfeaon
I am focusing on the problem recently.
我最近在关注这个问题。
as the Oracle document Thread.Statesays we can use LockSupport.park() to put the current thread into 'WAITING' or 'TIMED_WAITING' state.
正如 Oracle 文档Thread.State所说,我们可以使用 LockSupport.park() 将当前线程置于“WAITING”或“TIMED_WAITING”状态。
so when you try the LockSupport.unpark(), the specified thread will return to 'RUNNABLE' from 'WAITING'/'TIMED_WAITING'. (I am not sure whether it will go through the 'BLOCKED' state)
因此,当您尝试LockSupport.unpark() 时,指定的线程将从 'WAITING'/'TIMED_WAITING' 返回到 'RUNNABLE'。(我不确定它是否会通过“BLOCKED”状态)