首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测谁持有公平ReentrantReadWriteLock的读锁?

如何检测谁持有公平ReentrantReadWriteLock的读锁?
EN

Stack Overflow用户
提问于 2022-07-13 08:38:11
回答 1查看 115关注 0票数 1

至于公平的ReentrantReadWriteLock,如果线程t1持有读锁并忘记解锁,而线程t2试图获取写入锁,那么所有试图获取读或写锁的后续线程都将永远阻塞。

但是,jstack -l只能检测哪个线程持有写入锁,但不能检测哪个线程持有读锁。

有没有一种方法可以检测哪个线程持有读锁?

例如,

代码语言:javascript
复制
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的结果如下。在Locked ownable synchronizers of Thread-0中什么都没有。

代码语言:javascript
复制
"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
EN

回答 1

Stack Overflow用户

发布于 2022-07-16 17:07:19

这个程序中的问题主要是因为t2线程,它试图获得一个写锁,原因是它想要一个互斥锁。它不会获得这个锁,因为线程t1未能解锁读取锁。但是,线程t3将不受影响,因为它正在寻找处于共享模式的读锁,因此即使t1没有解锁读锁,t3仍然可以工作。因此,这个程序的唯一方法是,如果线程t2是第一个获得锁(即写锁)的线程。

关于如何获得具有锁的线程的名称的实际问题,我没有这个问题的答案。但是问题是,如果它是一个没有被解锁的写锁,那么在某个时候,只有一个线程会有一个写锁,因为它是相互排斥的,所以我相信jStack可以很容易地检测和显示这一点。但是,当涉及到试图获得读锁的线程时,可能会有几个线程导致问题。希望这能回答这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72963244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档