Difference between WAIT and BLOCKED thread states
Asked Answered
N

6

146

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.

Numerable answered 28/3, 2013 at 11:18 Comment(4)
check answer in this thread https://mcmap.net/q/160905/-java-thread-wait-gt-blocked also this link may provide further clarification geekexplains.blogspot.cz/2008/07/…Weighted
@Abdul the geekexplains link says that a thread can go into a blocked state by calling Object.wait() that's not correct is it?Numerable
according to oracle docs docs.oracle.com/javase/6/docs/api/java/lang/…: 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.parkWeighted
For the record, I think @Flavio's answer is a bit better than Ankit's in case you might consider changing.Faxan
J
126

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.

Jauregui answered 28/3, 2013 at 11:26 Comment(5)
You explained it much better because you explained the sequence in which a thread reaches those two states which makes it clearer than just explaining each of the two states in isolation (which is done by "More Than Five"'s answerYorktown
For all those, who wonder why most (all?) of the state diagrams found in the web claim, that notify()/notifyAll() results in RUNNABLE instead of BLOCKED: #28379092Parallelepiped
Assume there is only one thread and waited on some time in millis; now Is it possible a thread can directly from waiting state to go to runnable state? since no other thread takes lock here since only single threaded?Carolanncarole
There is a wait(time) method which will get back to runnable state once the time has elapsed. But if no time is specified, it will wait till other thread notifies or the thread is interrupted.Jauregui
Your answer is good but it doesn't quite explain that you can enter a Blocked state anytime you try to acquire a lock. It doesn't have to have anything to do with signal/notify.Faxan
A
110

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.

Ainslee answered 28/3, 2013 at 11:24 Comment(7)
is it correct to say that only a thread itself can make it go into wait? Can Thread-B ever make Thread-A go to WAIT state?Numerable
And why would you ever want to use wait state. I can understand Thread.join() but surely it is better to stay away from this construct and to instead always make threads just think about the data they want to access rather than interacting with other threads?Numerable
yes, only a thread itself can make it go to wait. You want a wait state because you don't want to loop on sleep(100ms) before a foreign action finally take placeLecce
You rarely use Object.wait() directly, but you end up in the WAITING state also using the more high-level concurrency constructs - like locks, blocking queues, etc... broadly speaking, whenever two threads have to coordinate.Ainslee
From personal experience, threads waiting for IO (e.g. reading from a Socket) are in RUNNING state.Ainslee
Java8 doc for Thread.State says, "...These states are virtual machine states which do not reflect any operating system thread states." In other words, the JVM does not care about the difference between a thread that is running Java code, a thread that is waiting for a system call to return, or a thread that is waiting for a time slice. Those are all just RUNNABLE as far as the JVM is concerned.Neogothic
It might be nice to add that when a thread moves from the WAITING state, it must first go to the BLOCKED state until it can acquire the lock associated with the object which it was waiting on.Faxan
D
47

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

Dicta answered 7/5, 2017 at 12:21 Comment(9)
Is that because it is some other threads responsibility to call notify() on the monitor object?Blanc
@berimbolo: I don't understand what you're askingDicta
It was in regard to why a waiting thread is not something the scheduler need worry about. I wondered if that was because another thread will be responsible for calling notify if it's waiting.Blanc
@berimbolo: the waiting Thread eventually gets woken by a notify. The scheduler would decide which waiting thread gets notified.Dicta
counts something, you are saying spin-lock, BLOCKED dose not mean it is spin-lockBismuth
@Frank: I didn't use that term. I don't know what point you're trying to make here.Dicta
notify is the one to be used if this behavior should be avoided. But just for the information of some who thinks notify is the better one always. notifyAll is the one to be used if your application should progress without a deadlock-like situation (if your application has the possibility to be in this situation and if it happens your application will not work as you intended) due to "missed signal" ( here, the intended thread misses the signal because the signal reached some other thread which is not the intended one ) See https://mcmap.net/q/80882/-java-notify-vs-notifyall-all-over-againRegurgitation
@user104309: ok, tried to add something to cover this. seems better to use ReentrantLock with multiple Conditions for this case.Dicta
How to decide the priority of these blocked threads?Giulia
F
29

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.

Frenzy answered 28/2, 2016 at 10:17 Comment(3)
I like your explanation. That's exactly what I'm trying to do in analyzing thread dumps right now :)Prisoner
@MuhammadGelbana Yeah, you are right, I have deleted the comment.Flynt
Your RUNNABLE is not quite right. It could be in the Java run queue but not executing or it could be executing Java code. It doesn't have to be calling out to native-land.Faxan
I
3

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.

Indican answered 3/2, 2016 at 10:45 Comment(0)
G
-2

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();
        }
    }
}
}
Gallo answered 7/5, 2017 at 11:2 Comment(2)
Thanks for the code but I'd rather you have a textual answer and then show a small code block.Faxan
it would be useful if the code was crystal clear to reason throughPiapiacenza

© 2022 - 2024 — McMap. All rights reserved.