Difference between WAIT and BLOCKED thread states

JavaMultithreadingBlockWait

Java Problem Overview


What is the difference between thread state WAIT and thread state BLOCKED?

The Thread.State documentation:

> Blocked
> A thread that is blocked waiting for a monitor lock is in this state. > > Waiting
> A thread that is waiting indefinitely for another thread to perform a particular action is in this state

does not explain the difference to me.

Java Solutions


Solution 1 - Java

The difference is relatively simple.

In the BLOCKED state, a thread is about to enter a synchronized block, but there is another thread currently running inside a synchronized block on the same object. The first thread must then wait for the second thread to exit its block.

In the WAITING state, a thread is waiting for a signal from another thread. This happens typically by calling Object.wait(), or Thread.join(). The thread will then remain in this state until another thread calls Object.notify(), or dies.

Solution 2 - Java

A thread goes to wait state once it calls wait() on an Object. This is called Waiting State. Once a thread reaches waiting state, it will need to wait till some other thread calls notify() or notifyAll() on the object.

Once this thread is notified, it will not be runnable. It might be that other threads are also notified (using notifyAll()) or the first thread has not finished his work, so it is still blocked till it gets its chance. This is called Blocked State. A Blocked state will occur whenever a thread tries to acquire lock on object and some other thread is already holding the lock.

Once other threads have left and its this thread chance, it moves to Runnable state after that it is eligible pick up work based on JVM threading mechanism and moves to run state.

Solution 3 - Java

The important difference between the blocked and wait states is the impact on the scheduler. A thread in a blocked state is contending for a lock; that thread still counts as something the scheduler needs to service, possibly getting factored into the scheduler's decisions about how much time to give running threads (so that it can give the threads blocking on the lock a chance).

Once a thread is in the wait state the stress it puts on the system is minimized, and the scheduler doesn't have to worry about it. It goes dormant until it receives a notification. Except for the fact that it keeps an OS thread occupied it is entirely out of play.

This is why using notifyAll is less than ideal, it causes a bunch of threads that were previously happily dormant putting no load on the system to get woken up, where most of them will block until they can acquire the lock, find the condition they are waiting for is not true, and go back to waiting. It would be preferable to notify only those threads that have a chance of making progress.

(Using ReentrantLock instead of intrinsic locks allows you to have multiple conditions for one lock, so that you can make sure the notified thread is one that's waiting on a particular condition, avoiding the lost-notification bug in the case of a thread getting notified for something it can't act on.)

Solution 4 - Java

Simplified perspective for interpreting thread dumps:

  • WAIT - I'm waiting to be given some work, so I'm idle right now.
  • BLOCKED - I'm busy trying to get work done but another thread is standing in my way, so I'm idle right now.
  • RUNNABLE...(Native Method) - I called out to RUN some native code (which hasn't finished yet) so as far as the JVM is concerned, you're RUNNABLE and it can't give any further information. A common example would be a native socket listener method coded in C which is actually waiting for any traffic to arrive, so I'm idle right now. In that situation, this is can be seen as a special kind of WAIT as we're not actually RUNNING (no CPU burn) at all but you'd have to use an OS thread dump rather than a Java thread dump to see it.

Solution 5 - Java

Blocked- Your thread is in runnable state of thread life cycle and trying to obtain object lock. Wait- Your thread is in waiting state of thread life cycle and waiting for notify signal to come in runnable state of thread.

Solution 6 - Java

see this example:

demonstration of thread states.

/*NEW- thread object created, but not started.
RUNNABLE- thread is executing.
BLOCKED- waiting for monitor after calling wait() method.
WAITING- when wait() if called & waiting for notify() to be called.
  Also when join() is called.
TIMED_WAITING- when below methods are called:
 Thread.sleep
 Object.wait with timeout
 Thread.join with timeout
TERMINATED- thread returned from run() method.*/
public class ThreadBlockingState{

public static void main(String[] args) throws InterruptedException {
	Object obj= new Object();
	Object obj2 = new Object();
	Thread3 t3 = new Thread3(obj,obj2);
	Thread.sleep(1000);
	System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+
			",when Wait() is called & waiting for notify() to be called.");
	Thread4 t4 = new Thread4(obj,obj2);
	Thread.sleep(3000);
	System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2.");
	System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called.");
}

}
class Thread3 extends Thread{
Object obj,obj2;
int cnt;
Thread3(Object obj,Object obj2){
	this.obj = obj;
	this.obj2 = obj2;
	this.start();
}

@Override
public void run() {
	super.run();
	synchronized (obj) {
		try {
			System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait().");
			obj.wait();				
			System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait().");
			synchronized (obj2) {
				cnt++;
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
}
class Thread4 extends Thread{
Object obj,obj2;
Thread4(Object obj,Object obj2){
	this.obj = obj;
	this.obj2 = obj2;
	this.start();
}

@Override
public void run() {
	super.run();
	synchronized (obj) {
		System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify().");
		obj.notify();
		System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify().");
	}
	synchronized (obj2) {
		try {
			Thread.sleep(15000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMore Than FiveView Question on Stackoverflow
Solution 1 - JavaFlavioView Answer on Stackoverflow
Solution 2 - JavaAnkit BansalView Answer on Stackoverflow
Solution 3 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 4 - JavaoldguyView Answer on Stackoverflow
Solution 5 - JavaPrakash BishtView Answer on Stackoverflow
Solution 6 - JavamuraliView Answer on Stackoverflow