简体   繁体   中英

How is a thread in blocked state caused by waiting on a objects lock handled by the JVM

I have seen there are different ways a thread could get to blocked state. Im interested to know what exactly happens after a thread is in blocked state. How does it get back to running state. If its blocked by sleep(time) then it moves to the runnable queue after time milli secs. If its blocked on a I/O operation it gets into the runnable queue once that is done. how does it get to the runnable queue when it is waiting on an objects lock. how does it know that the lock on the ocject its waiting for is now available. Can some one also explain the internals of how the blocked thread on I/O works. Please correct me if my understanding on any of the above topics isn't right..

Thank you

How does it get to the runnable queue when it is waiting on an objects lock?

If the thread is blocked due to trying to enter a synchronized block, the thread is automatically marked as runnable when the other thread (holding the lock) releases the lock by exiting from a synchronized block of the same object.

If the current thread is blocked due to a call to someObject.wait() , the thread is "released" when another thread calls someObject.notify() .

On the bytecode level it looks as follows:

[load some object, obj, onto the operand stack]
monitorenter  // grab the lock

// do stuff

[load obj onto the operand stack again] 
monitorexit   // release the lock

If someone else already holds the lock of obj , the thread will hang on monitorenter until the other thread calls monitorexit .

The exact details of how monitorenter and monitorexit should be implement is not specified by the JLS. That is, it is JVM/OS dependent.

For further details, refer to JLS Wait Sets and Notifications .

On a close-to-code level it looks like this:

Thread 1:

Object mutex = new Object();
....
synchronized(mutex) {
    //lock to mutex is acquired.
    mutex.wait(); //lock to mutex is released. Thread is waiting for somebody to call notify().
    doSomething();
}

Thread 2:

synchronized(Thread1.mutex) {
    //acquires the lock on mutex. 
    //Can be done only after mutex.wait() is called from Thread1
    // and the lock is released
    Thread1.mutex.notify(); // notifies Thread1 that it can be resumed.
}

In general you should keep in mind that Thread.sleep() holds the lock on the resources, but Thread.wait() releases the locks and can be notified by other Threads.

AFAIK JVM use native threads. So it is OS not JVM that manage thread schedule and context switching.

You can look at actual JVM source code. It's open.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM