How To Troubleshoot Collaboration Apps for the Modern Connected Worker
Java reentrant lock tutorial by jeetendra mandal
1.
2. When a thread fails to acquire the lock, it gets added to a waiting
queue. It can be unblocked either by the thread holding the lock or by
interrupting it.
3. When we call ReentrantLock.lock(), we acquire lock in a non-interruptible mode which means
even if the thread waiting in queue is interrupted or unparked, it is going to simply retry
acquiring the lock. This goes on, resulting in blocking and unblocking of the thread till it
acquires the lock.
4. We can try acquiring lock in exclusive interruptible mode using ReentrantLock.lockInterruptibly() in which
case if the thread in waiting is interrupted by some other thread it will result in InterruptedException thus
there won’t be any retry. If the thread is unparked as a result of release of lock then it is going to retry
acquiring lock.
5. A reentrant lock is a mutually exclusive lock similar to synchronized keyword. But with more
capabilities than the synchronization.
As you know thread scheduler always tries to give the priority to the maximum priority thread.
Sometimes it may be caused to the starvation state. But The Reentrant lock assured
the fairness to the threads than the synchronization. Also, reentrant lock can provide a lock to
longest waiting thread in the system
How does it work?
ReentrantLock object is created as an instance variable of the class. It is an implementation of
the Lock interface. java.util.concurrent.locks package consists of both methods. You may feel the
name of this reentrant lock is a bit awkward. But its functionality is defined by its name also.
The ReentrantLock allows a thread to acquire a lock it already owns multiple time recursively.
The number of times that a thread acquires a lock is stored in a hold count variable. When the
thread acquires the lock, the hold count is increased by 1, and when it releases the lock, hold
count is decreased by 1. The lock is completely relinquished if hold count is 0. So there must be
a call to unlock() for every call to lock().
6. Difference between Synchronized keyword and ReentrantLock in Java
If you want to lock a thread interruptible and ofcause without a timeout method I
recommend you to use the ReentrantLock. If you trying to lock a thread interruptibly
using the synchronized way you need to block the thread infinitely.
1.The synchronized keyword does not support the fairness — When using ReentrantLock you can
call the fairness property and it will lock to the longest waiting thread
2.The second difference between synchronized and ReentrantLock is the lock() method.
ReentrantLock provides a convenient lock() method, which acquires lock only if its available or not
held by any other thread. This reduces the blocking of thread waiting for lock-in Java application.
3.As mentioned above ReentrantLock provides a method called lockInterruptibly() which can be
used to interrupt thread when the thread is waiting for the lock. But when using synchronized, the
thread can be blocked waiting for a lock for a long time.
8. •lock(): Call to the lock() method increments the hold count by 1 and gives the lock to the thread if the shared
resource is initially free.
•unlock(): Call to the unlock() method decrements the hold count by 1. When this count reaches zero, the resource is
released.
•tryLock(): If the resource is not held by any other thread, then call to tryLock() returns true and the hold count is
incremented by one. If the resource is not free, then the method returns false, and the thread is not blocked, but exits.
•tryLock(long timeout, TimeUnit unit): As per the method, the thread waits for a certain time period as defined by
arguments of the method to acquire the lock on the resource before exiting.
•lockInterruptibly(): This method acquires the lock if the resource is free while allowing for the thread to be
interrupted by some other thread while acquiring the resource. It means that if the current thread is waiting for the
lock but some other thread requests the lock, then the current thread will be interrupted and return immediately
without acquiring the lock.
•getHoldCount(): This method returns the count of the number of locks held on the resource.
•isHeldByCurrentThread(): This method returns true if the lock on the resource is held by the current thread.
ReentrantLock() Methods
9. It is recommended practice to always immediately follow a call to lock with
a try block, most typically in a before/after construction such as:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ... public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
} }