views:

76

answers:

3

What happens to a Thread that fails to acquire a lock (non-spin)? It goes to the BLOCKED state. How does it gets executed again?

Lock lck = new ReentrantLock();
lck.lock()
try
{
}
finally
{
   lck.unlock();
}
+2  A: 

The scheduler (or the underlying Lock implementation) is responsible for getting it running again. If the lock action was translated into a mutex call all the way into the kernel, the scheduler will not reschedule the thread until the mutex becomes available; then the OS scheduler will re-awaken the thread. Reading the wikipedia page on Context Switch and links from there might provide more insight into the detailed mechanisms involved. You can also look directly at the code for ReentrantLock though that will eventually boil your question down to some combination of primitives including AbstractedQueuedSynchronizer, various atomic operations, and maybe LockSupport.park() and unpark(). You might augment your question or ask a new one if you're specifically interested in kernel-level blocking/context switches or specifically how various Java primitives (e.g., j.u.c.Lock or primitive object monitors) are implemented atop the kernel.

In practice, because this is costly, this may be optimized away by the JVM or lock implementation. For instance, the thread may actually spin for a bit to see if the lock is freed before actually blocking.

Note that a Java thread may report the state BLOCKED even if the underlying OS thread is not blocked, specifically in the adaptive spinning cases described in the performance whitepaper below.

There are some great resources out there to learn about concurrency control in Java. Leading the pantheon is Java Concurrency in Practice. Some interesting discussion of synchronization performance in HotSpot 6.0 in the Java SE 6 Performance Whitepaper and some related slides.

andersoj
A: 

The thread holding the lock unlocks the lock and then the (or "a") blocked thread is woken up. If the thread holding the lock never releases the lock (perhaps because it's blocked on another resource) then you get deadlock. A non-spinning lock will typically use the wait()/notify() primitives or something similar such that the thread is notified when the lock again becomes available.

Mark Peters
+1  A: 
erickson
Lock acquisition does fail! When your application deadlocks and you forcibly kill the process! ;-)
andersoj
Nah, you just didn't give it a chance. Eventually, given a few billion years, some quantum fluctuation would flip the right bit and one of the threads would give up its lock.
erickson
Hot damn, I should write that into my next DoD performance spec... quantum mechanics is the ultimate out.
andersoj