Using ReentrantLock for thread synchronization
ReentrantLock was introduced in Java 1.5. This can be considered as a replacement for the traditional “wait-notify” method. The basic concept is, every thread need to acquire the lock before entering in to the critical section and should release it after finishing it. And its the most basic concept of synchronization.
ReentrantLock eliminates the use of “synchronized” keyword.
import java.util.concurrent.locks.ReentrantLock;
final ReentrantLock _lock = new ReentrantLock();
private void method() throws InterruptedException
{
//Trying to enter the critical section
_lock.lock(); // will wait until this thread gets the lock
try
{
// critical section
}
finally
{
//releasing the lock so that other threads can get notifies
_lock.unlock();
}
}
Using optional “fairness” parameter with ReentrantLock
ReentrantLock accepts an optional “fairness” parameter in it’s constructor. Normally what happens is, whenever a thread releases the lock anyone of the waiting threads will get the chance to acquire that lock. But there is no predefined order or priority in the selection of the thread (at least from a programmers perspective).
But if we are specifying the fairness parameter as “true” while creating a new ReentrantLock object, it gives us the guaranty that the longest waiting thread will get the lock next. Sounds pretty nice right?
Use of “Condition” in ReentrantLock
Condition can be considered as a separation of monitor methods (wait(), notify() & notifyAll()). For each ReentrantLock we can define a set of conditions and based on that we can make the threads waiting & things like that.
import java.util.concurrent.locks.Condition;
final Condition _aCondition = _lock.newCondition();
private void method1() throws InterruptedException
{
_lock.lock();
try
{
while (condition 1)
{
// Waiting for the condition to be satisfied
// Note: At this time, the thread will give up the lock
// until the condition is satisfied. (Signaled by other threads)
_aCondition.await();
}
// method body
}
finally
{
_lock.unlock();
}
}
private void method2() throws InterruptedException
{
_lock.lock();
try
{
doSomething();
if (condition 2)
{
// Signaling other threads that the condition is satisfied
// Wakes up any one of the waiting threads
_aCondition.signal();
// Wakes up all threads waiting for this condition
_aCondition.signalAll();
}
// method body
}
finally
{
_lock.unlock();
}
}
Update [ Subinkrishna on 19-Feb-2009]
The main difference between RentrantLock and traditional “synchronized” is that, if we are using ReentrantLock, the thread can temporarily release the locks it has when it is going to a wait state. This feature is not available in the traditional way and this can considerably reduce the deadlock situations.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html


yuv11 2:53 pm on October 27, 2009 Permalink
I believe even in synchronized block/method call to wait() does release an object lock. Thats why some other thread can acquire and notify() on completion.
Subinkrishna G 11:39 am on October 28, 2009 Permalink
yuv11, I am not sure whether a thread can release the locks it holds already (if that thread is using wait-notify), while waiting for another one. I don’t think it can.
eniosp 2:15 pm on January 31, 2010 Permalink
The wait releases the lock. From the Object’s class javadoc (wait method):
The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
Subinkrishna G 10:42 am on February 1, 2010 Permalink
@eniosp,
Thanks for the update.
javabreadjam 8:21 am on February 9, 2010 Permalink
so basically _aCondition.await(); in your code
is same as obj.wait() since both give up locks on the object . so your eaxmple is just another way. Only thread.sleep() gives up the lock
Noman Khan 9:45 pm on February 25, 2010 Permalink
Interesting.
eniosp 5:01 pm on February 26, 2010 Permalink
@javabreadjam,
thread.sleep DOES NOT release the lock. The object keeps the monitor.
From Thread.sleep javadoc:
“Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. The thread does not lose ownership of any monitors.”
javarevisited 5:42 am on May 11, 2011 Permalink
wonderful example and explanation , ideal for any beginner. just to add by using re-entrant lock we can build sophisticated cache which support behavior of concurrenthashMap i.e. allowing multiple read concurrently. this is not possible with synchronized keyword in java as it lock both reader and writer. I have blogged some of my experience as How Synchronization works in Java , you may find it interesting.