What do you actually use for this method lockInterruptibly
? I have read the API however it's not very clear to me. Could anybody express it in other words?
The logic is the same as for all interruptible blocking methods: it allows the thread to immediately react to the interrupt
signal sent to it from another thread.
How this particular feature is used is up to the application design. For example, it can be used to kill a contingent of threads in a pool which are all waiting to aquire a lock.
lockInterruptibly
continuously tests for them explicitly? –
Ethelstan interrupted
flag, it will be notified and when it resumes, it will throw the InterruptedException
–
Anthropophagi lockInterruptibly()
may block if the the lock is already held by another thread and will wait until the lock is aquired. This is the same as with regular lock()
. But if another thread interrupts the waiting thread lockInterruptibly()
will throw InterruptedException
.
lockInterruptibly()
is identical to lock()
unless your code calls interrupt()
at some point. –
France The logic is the same as for all interruptible blocking methods: it allows the thread to immediately react to the interrupt
signal sent to it from another thread.
How this particular feature is used is up to the application design. For example, it can be used to kill a contingent of threads in a pool which are all waiting to aquire a lock.
lockInterruptibly
continuously tests for them explicitly? –
Ethelstan interrupted
flag, it will be notified and when it resumes, it will throw the InterruptedException
–
Anthropophagi Try to understand this concept through below code example.
Code Sample:
package codingInterview.thread;
import java.util.concurrent.locks.ReentrantLock;
public class MyRentrantlock {
Thread t = new Thread() {
@Override
public void run() {
ReentrantLock r = new ReentrantLock();
r.lock();
System.out.println("lock() : lock count :" + r.getHoldCount());
interrupt();
System.out.println("Current thread is intrupted");
r.tryLock();
System.out.println("tryLock() on intrupted thread lock count :" + r.getHoldCount());
try {
r.lockInterruptibly();
System.out.println("lockInterruptibly() --NOt executable statement" + r.getHoldCount());
} catch (InterruptedException e) {
r.lock();
System.out.println("Error");
} finally {
r.unlock();
}
System.out.println("lockInterruptibly() not able to Acqurie lock: lock count :" + r.getHoldCount());
r.unlock();
System.out.println("lock count :" + r.getHoldCount());
r.unlock();
System.out.println("lock count :" + r.getHoldCount());
}
};
public static void main(String str[]) {
MyRentrantlock m = new MyRentrantlock();
m.t.start();
System.out.println("");
}
}
Output:
lock() : lock count :1
Current thread is intrupted
tryLock() on intrupted thread lock count :2
Error
lockInterruptibly() not able to Acqurie lock: lock count :2
lock count :1
lock count :0
A thread that uses lockInterruptibly()
can be interrupted by another thread. So, invocation to lockInterruptibly()
throws InterruptedException
which can be caught, and useful stuff can be done within the catch block like releasing the held lock, so that the other thread that has caused the interrupt to happen can gain access to the released lock. Think of the case where you have a common data structure with the below read and write constraints:
- A single thread is responsible for writing to the common data structure.
- There is a single reader thread.
- When a write is in process, read should not be allowed.
To fulfil the above constraints, the reader thread can use lockInterruptibly()
to gain access to the java.util.concurrent.locks.ReentrantLock
. That means the reader thread can be interrupted any time amidst processing by the writer thread. Writer thread would have access to the reader thread instance, and writer can interrupt the reader. When the reader receives the interrupt, in the catch block of the InterruptedException
, the reader should unlock
the hold on the ReentrantLock
and await notification from the writer thread to proceed further. The writer thread can acquire the same lock using tryLock
method. Code snippet for the reader and writer threads is given below:
Common fields accessed by both reader and writer threads:
ReentrantLock commonLock = new ReentrantLock(); //This is the common lock used by both reader and writer threads.
List<String> randomWords = new ArrayList(); //This is the data structure that writer updates and reader reads from.
CountDownLatch readerWriterCdl = new CountDownLatch(1); //This is used to inform the reader that writer is done.
Reader:
try {
if(!commonLock.isHeldByCurrentThread())
commonLock.lockInterruptibly();
System.out.println("Reader: accessing randomWords" +randomWords);
} catch (InterruptedException e) {
commonLock.unlock();
try {
readerWriterCdl.await();
}
catch (InterruptedException e1) {
}
}
Writer:
if(commonLock.isLocked() && !commonLock.isHeldByCurrentThread())
{
readerThread.interrupt();
}
boolean lockStatus = commonLock.tryLock();
if(lockStatus) {
//Update the randomWords list and then release the lock.
commonLock.unlock();
readerWriterCdl.countDown();
readerWriterCdl = new CountDownLatch(1);
}
lockInterruptibly()
. But if only the reader and writer acquire the lock, then there's never a situation where the reader would be interrupted while waiting to acquire the lock (if the reader is waiting, the writer has the lock and won't interrupt the reader). –
Schleiermacher Based on Evgeniy Dorofeev's answer, I just deliberately come up with such demo but I really I have no clue where is exactly, it could be used. Perhaps this demo could help a tad :)
private static void testReentrantLock() {
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(() -> {
int i = 0;
System.out.println("before entering ReentrankLock block");
try {
lock.lockInterruptibly();
while (0 < 1) {
System.out.println("in the ReentrankLock block counting: " + i++);
}
} catch (InterruptedException e) {
System.out.println("ReentrankLock block interrupted");
}
});
lock.lock(); // lock first to make the lock in the thread "waiting" and then interruptible
thread.start();
thread.interrupt();
}
Output
before entering ReentrankLock block
ReentrankLock block interrupted
© 2022 - 2024 — McMap. All rights reserved.