How does it get into the runnable queue when it waits for objects to lock?
If a thread is blocked due to an attempt to enter a synchronized block, the thread is automatically marked as executed when another thread (holding the lock) releases the lock, exiting the synchronized block of the same object.
If the current thread is blocked by calling someObject.wait() , the thread is "freed" when another thread calls someObject.notify() .
At the bytecode level, it looks like this:
[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 holds the obj lock, the thread will hang on monitorenter until another thread calls monitorexit .
The exact details of how monitorenter and monitorexit should be implemented are not specified by JLS. That is, it depends on the JVM / OS.
See JLS Wait Sets and Notifications for more information .
source share