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