Reputation: 187
As for the fair ReentrantReadWriteLock
, if the thread t1
holds the read lock and forgets to unlock, and the thread t2
try to acquire the write lock, then all the follow-up threads who try to acquire the read or write lock will block forever.
However, jstack -l
can only detect which thread holds the write lock, but cannot detect which thread holds the read lock.
Is there a way to detect which thread holds the read lock?
For example,
public static void main(String[] args) throws InterruptedException {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
Thread t1 = new Thread(() -> {
lock.readLock().lock();
try {
// Sleep long time.
Thread.sleep(1000_000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
Thread t2 = new Thread(() -> {
lock.writeLock().lock();
try {
System.out.println("t2");
} finally {
lock.writeLock().unlock();
}
});
t2.start();
Thread t3 = new Thread(() -> {
lock.readLock().lock();
try {
System.out.println("t3");
} finally {
lock.readLock().unlock();
}
});
t3.start();
t1.join();
t2.join();
t3.join();
}
jstack -l
result is as follows.
There is nothing in Locked ownable synchronizers
of Thread-0
.
"Thread-2" #13 prio=5 os_prio=31 tid=0x00007f7d0c04e000 nid=0x5903 waiting on condition [0x000070000d399000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076ac17400> (a java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:967)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:1283)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(ReentrantReadWriteLock.java:727)
at WaWaMain.lambda$main$2(WaWaMain.java:30)
at WaWaMain$$Lambda$3/1149319664.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"Thread-1" #12 prio=5 os_prio=31 tid=0x00007f7d0c04d000 nid=0x5703 waiting on condition [0x000070000d296000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076ac17400> (a java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:943)
at WaWaMain.lambda$main$1(WaWaMain.java:20)
at WaWaMain$$Lambda$2/558638686.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"Thread-0" #11 prio=5 os_prio=31 tid=0x00007f7d0c809000 nid=0x5503 waiting on condition [0x000070000d193000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at WaWaMain.lambda$main$0(WaWaMain.java:12)
at WaWaMain$$Lambda$1/1747585824.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
Upvotes: 1
Views: 378
Reputation: 342
The problem in this program is mainly for the t2 thread which is trying to get a write lock and the reason is that it wants a mutually exclusive lock. It will not get this lock since thread t1 has failed to unlock the read lock. However thread t3 will be unaffected since it is looking for a read lock which is in shared mode and hence even if t1 has not unlocked the read lock, t3 will still work. So the only way this program would go ahead is if thread t2 is the first thread to get a lock ie the write lock.
With regard to your actual question how to get the name of the thread that has the lock, I don't have the answer to that question. But the problem is if it is a write lock that has not been unlocked then at a point of time only one thread would have a write lock since it is mutually exclusive so jStack can easily detect and show this I believe. But when it comes to threads trying to get a read lock then there could be several threads causing the issue. Hope this answers the question.
Upvotes: 0