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