Java reentrant lock tutorial by jeetendra mandal

jeetendramandal1 144 views 10 slides Oct 31, 2021
Slide 1
Slide 1 of 10
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10

About This Presentation

Java reentrant lock tutorial


Slide Content

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.

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.

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.

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().

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. 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 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. 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.

public void some_method () { reentrantlock.lock (); try { //Do some work } catch(Exception e) { e.printStackTrace (); } finally { reentrantlock.unlock (); } } ReentrantLock () Example  

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 

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 () } } }