Difference between Waiting and Blocked in Thread.State - java

This question confused me a lot since I read its official explanation about Thread.State.
Blocked
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.
Waiting
A thread in the waiting state is waiting for another thread to perform a particular action. For example, a thread that has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on that object. A thread that has called Thread.join() is waiting for a specified thread to terminate.
Also I read some wonderful answers like Difference between WAIT and BLOCKED thread states in StackOverflow, but still I am not quite sure about Waiting and Blocking.
Is it right to think about these two states as follows?
Waiting: threads positively execute wait() or sleep() to give up the CPU cycles;
Blocking: threads trying to move on but the essential resources like synchronized block are taken up by others, so they have to negatively be waited;

When a thread is in waiting state it releases the lock of the object it holds and will remain in WAITING state until any other thread calls either notify() or notifyAll() on the same object. Where a BLOCKED thread is waiting for other thread to release the lock it wants.

Related

Java thread state transition, WAITING to BLOCKED, or RUNNABLE?

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?
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.
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)
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)
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.

how can sleep() method help other threads to execute, since it holds lock on that object itselt?

I have heared that sleep(timeInMilliseconds) method in java holds lock on object and goes to sleep for specified period of time. And I also read that it gives chance to other threads to execute in that sleeping period? How can the sleep() method help to other threads if it hols lock on object the other threads wants to use ?
The major difference between sleep() and wait() is that wait() releases the lock or monitor while sleep() doesn’t releases any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution.
Thread.sleep() keeps the monitors it has acquired (if any).
Object.wait() sends the current thread (note that you apply it on the Object) into the “Not Runnable” state, like Thread.sleep(), but, again wait() is called on an Object, not on a Thread. Since the object is the lock and the thread-object is currently on a "non running state" the lock is released.
If the thread has not acquired any lock before sleeping, it wouldn't hold any lock. if it has, then YES, sleep() won't give chance to any other thread who is waiting to acquire lock on the object which the sleeping thread has acquired lock on.
So, sleep() just puts the thread to sleep for specified time, with all lock it has acquired (if acquired) in locked state.

doing lot of work after notify() will cause wait() become busy wait?

if i have the below piece of code
synchronized (this)
{
System.out.println("Waiting for return key.");
scanner.nextLine();
System.out.println("Return key pressed.");
notify();
Thread.sleep(5000);
}
After notify, I am calling sleep which means, I have notified the waiting thread but not relinquished the lock, what happens now.. After notifying the waiting thread would have been woken up but not able to acquire the lock, so from here on-wards, is it a busy wait? since we are not going to call notify again.
Same question goes with notify and notifyall, after one thread woken and acquired lock, is that all other thread waiting becomes busy wait?
wait() doesn't busy-wait, but it does "compete in the usual manner with other threads for the right to synchronize on the object" once notified.
A call to notify wakes up one thread that is currently waiting on the object's condition queue which then tries to reaquire the lock which is still held by the calling thread at that point of time. So the situation is comparable to a thread that wants to enter a synchronized block that is currently executed by another thread. The thread is not doing a busy-wait, it is just blocked until it can aquire the lock.
When the thread that called notify releases its lock, the other thread can be unblocked and continue to work.
The same is true for notifyAll, but it wakes up all threads that are waiting on the object's condition queue. As only one of them can acquire the lock, the others stay blocked until they get the lock - one after the other. This and because thread-awaking signals may happen spontaneous it is required to always call wait within a conditional loop:
synchronized (lockObject) {
// ...
while (!condition) {
lockObject.wait();
}
// object is now in desired state
}
See also: Java Concurrency in Practice, Chapter 14.2
A thread can wait on an object only when IT OWNS the object's monitor. Once the first thread notifies, the second thread wakes up but doesn't do anything. The only thing that happens here is that "The thread will be removed from the list of threads waiting on the object . It is left to the OS to schedule its execution. The OS might choose NOT to execute it for sometime. The thread doesn't busy-wait. It will just be in the set of threads which are waiting to be scheduled.
As #Holger points out, any thread which calls wait() releases the lock on the object. Once it is notified, it has to "compete" and reacquire the lock on the object. Reacquiring of lock doesn't happen when notify() is called by the thread which holds the lock. It happens when that thread exits its synchronized block.

Does a thread of execution goes to "waiting" state by executing wait() and join() both?

There are 3 states for a thread that is alive but is neither running not runnable:-
Sleeping
Blocked
Waiting
When a thread executes sleep() method, it goes into SLEEPING state from running state for the time period specified by its argument (say for some milliseconds).
When a thread is waiting for a lock on an object that is acquired by some other thread because of the synchronized method or block, it is BLOCKED by that thread.
So, can we say that a thread enters WAITING state when it executes wait() on some other thread?
Same is the case with calling join() on some thread.
So, can we say that both wait() (from java.lang.Object) and join() (from java.lang.Thread) shifts a thread's state to WAITING?
This is described in the javadoc of Thread.State:
public static final Thread.State WAITING
Thread state for a waiting thread. A thread is in the waiting state
due to calling one of the following methods:
Object.wait with no timeout
Thread.join with no timeout
LockSupport.park
A thread in the waiting state is waiting for another thread to perform
a particular action. For example, a thread that has called
Object.wait() on an object is waiting for another thread to call
Object.notify() or Object.notifyAll() on that object. A thread that
has called Thread.join() is waiting for a specified thread to
terminate.

is there any difference if thread is waiting for monitor to be freed before synchronized block or if it calls wait()

I've read many docs about thread states, some of them tells that there is two different states: blocked (before synchronized) and wait (if calls wait), some others are telling that there is only one state: wait. Moreover, some docs telling that you should call notify() for every wait() and if you don't then threads waiting() will never be eligible for execution even if monitor is unlocked.
From you last sentence I see you don't fully understand the difference between synchronized and wait()/notify().
Basically, monitor has lock and condition. It's almost orthogonal concepts.
When thread enters a synchronized block, it acquires a lock. When thread leaves that block, it releases a lock. Only one thread can have a lock on a particular monitor.
When thread having a lock calls wait(), it releases a lock and starts waiting on its condition. When thread having a lock calls notify(), one of the threads (all threads in the case of notifyAll()) waiting on the condition becomes eligible for execution (and starts waiting to acquire a lock, since notifying thread still has it).
So, waiting to acquire a lock (Thread.State.BLOCKED) and waiting on the monitor's condition (Thread.State.WAITING) are different and independent states.
This behaviour becames more clear if you look at Lock class - it implements the same synchronization primitives as synchronized block (with some extensions), but provides clear distinction between locks and conditions.
There are two different states BLOCKED and WAITING.
The part about waiting forever if no one notifies (or interrupts) you is true.
Standard doc is here
When a thread calls Object.wait
method, it releases this acquired
monitor and is put into WAITING (or
TIMED_WAITING if we call the timeout
versions of the wait method) state.
Now when the thread is notified either
by notify() or by notifyAll() call on
the same object then the waiting state
of the thread ends and the thread
starts attempting to regain all the
monitors which it had acquired at the
time of wait call. At one time there
may be several threads trying to
regain (or maybe gain for the first
time) their monitors. If more than one
threads attempt to acquire the monitor
of a particular object then only one
thread (selected by the JVM scheduler)
is granted the monitor and all other
threads are put into BLOCKED state.
In Java's perspective (Thread.State), there are two different states: BLOCKED and WAITING . When a thread synchronizes on a Object, it is in BLOCKED state. After a thread executes wait, it is in WAITING state.
On Linux platform, Java thread is OS native thread. The OS thread state for both BLOCKED and WAITING states is Interruptible sleep. When being checked with ps, the state for both BLOCKED and WAITING threads is "Sl+".

Categories