Java thread state transition, WAITING to BLOCKED, or RUNNABLE?
Asked Answered
R

4

35

There seems to be a discrepancy between SO consensus and nearly every Java thread state diagram on the Internet; specifically, regarding thread state transition from WAITING after notify() or notifyAll() is invoked...

  • WAITING never goes directly to RUNNABLE
  • The thread is WAITING until it is notified...Then it becomes BLOCKED...
  • 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.

Question

Why do most state diagrams on the web illustrate the transition from WAITING to RUNNABLE, not BLOCKED? Depiction in red shows the incorrect transition; am I missing something?

enter image description here

Rheinlander answered 7/2, 2015 at 4:36 Comment(6)
Why would I ask the person who drew the diagram when based on your comment they don't know better? :-)Rheinlander
I said "don't or didn't". If you ask them, they may discover that they are wrong. Or they may already have discovered.Pyx
So you're saying my diagram is more accurate than roughly 106,000 Google results? Hellulalua!Rheinlander
No. I doubt that there are 106,000 different state diagram images on the web ...Pyx
If that is the case, what is special with TIMED_WAIT ? why it is directly going back to RUNNABLE, instead of moving to BLOCKED ?Tonguelash
there are some clearer answers, if you need. https://mcmap.net/q/158258/-difference-between-wait-and-blocked-thread-states/2361308Reindeer
G
26

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.

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.

This is explained in the javadoc of 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.

Giffy answered 7/2, 2015 at 4:55 Comment(3)
Makes sense. But, surely that's true of TIMED_WAITING too then?Hootenanny
Except if it has entered the TIMED_WAITING state due to sleep(t) that is.Hootenanny
@Hootenanny According to the Thread.State javadoc, WAITING is for the parameterless Object#wait, while TIMED_WAITING is for the overload that accepts a wait time. Yes, this applies to both. Concerning sleep, a thread doesn't unlock any held monitors, it still owns them by the time it wakes up.Giffy
D
2

A thread is in WAITING state goes in BLOCK state,until it acquires monitor by notify and become RUNNABLE.

Same applies for TIMEDWAITING,it goes in BLOCK state,if monitor is hold by some other thread,even though specified time has passed.(your diagram need to be corrected)

Disclaimer answered 2/7, 2017 at 21:1 Comment(0)
C
0

I am focusing on the problem recently.

as the Oracle document Thread.State says we can use LockSupport.park() to put the current thread into 'WAITING' or 'TIMED_WAITING' state.

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)

Combustible answered 29/6, 2015 at 16:20 Comment(1)
I think LockSupport.unpark() will cause the specified thread state changing from WAITING to RUNNABLE directly.Lamm
C
0

It is worth to mention that is also true for Thread.interrupt() method during WAITING state while in lock.wait() method.

Thread.interrupt() method will firstly make WAITING thread BLOCKED with isInterrupted flag set to true, and only after reacquiring lock interrupted thread will be able to throw InterruptedException (that is obvious, as it cannot handle exception, by that continuing execution without having exclusive lock before). (example here)

Simply to say

Always WAITING -> BLOCKED to be able again compete for the lock, and after that to acquire it eventually and run its' code RUNNABLE.

Chlori answered 17/7, 2021 at 14:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.