当前位置: 首页 > 知识库问答 >
问题:

使用ReentrantReadWriteLock时,这是死锁吗?

酆英达
2023-03-14
"writer-0" #83 prio=5 os_prio=0 tid=0x00007f899c166800 nid=0x2b1f waiting on condition [0x00007f898d3ba000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000002b8dd4ea8> (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)

读者:

"reader-1" #249 daemon prio=5 os_prio=0 tid=0x00007f895000c000 nid=0x33d6 waiting on condition [0x00007f898edcf000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000002b8dd4ea8> (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)

这看起来像是一个僵局,但有几件事让我怀疑:

  • 我找不到另一个可能持有相同锁的线程
  • 4秒后进行线程转储会得到相同的结果,但现在所有线程都报告停车等待<0x00000002A7DAA878>,这与第一次转储中的0x00000002B8DD4EA8不同。

共有1个答案

姬承教
2023-03-14

这是僵局吗?

我不认为这是僵局的证据。至少,不是经典意义上的。

堆栈转储显示两个线程在同一个ReentrantReadWriteLock上等待。一个线程正在等待获取读锁。另一个等待获取写锁。

一种可能是第三个线程持有写锁(很长时间),这将使事情变得混乱。这个读写锁的争用太多了。

如果(假定的)第三个线程正在使用trylock,那么您可能有一个活锁...这可以解释“change”证据。但另一方面,线程也应该被停在...你说你没有看到。

另一种可能是您有太多的活动线程…而操作系统正在努力将它们调度到核心。

 类似资料:
  • 众所周知,有两种锁定策略:乐观锁定和悲观锁定 悲观锁定是锁定记录供您独占使用,直到您使用完它。它比乐观锁定具有更好的完整性,但是需要您小心应用程序设计以避免死锁。 也知道,乐观并发控制与多版本并发控制(Oracle或MSSQL-Snapshot/MVCC-RC)不同:乐观与多版本并发控制-差异? 但是,如果在两个事务中都使用OCC(乐观并发控制),会在两个交易之间发生死锁吗? 我们可以说乐观锁通过

  • 我熟悉在一个账户和另一个账户之间转账时使用同步的并发示例,例如,两个账户的锁定是按账号顺序进行的,这样就不会发生死锁。 我想探索使用Reenter antReadWriteLock,因为在我看来,这将允许帐户对象的客户端进行并发读取,前提是没有客户端更新该对象。 我已经编写了代码并对其进行了测试,它似乎可以工作,但看起来有点难看,例如,Account类暴露其锁对象看起来有点奇怪,但它似乎必须这样做

  • 问题内容: 我有一个Java Servlet应用程序,并且正在使用准备好的查询来更新SQL Server数据库表中的记录。 可以说我要执行。(是的,id是一个varchar) 我使用以下代码来实现此目的: 我发现运行JMeter脚本模拟2个用户时,此语句在数据库中导致死锁。 我想检查一下SQL事件探查器中的值,因此我使用了以下代码,因此可以检查这些值。 突然我的僵局消失了!遗憾的是,最后一种方法容

  • 问题内容: 我有一个客户端服务器程序在服务器端使用套接字,并且读写发生在这种方式 同样在cilent(android)方面… 问题是,建立连接后,程序会卡住它们,没有错误,也没有异常。停下来 问题答案: 这是一个死锁,您必须首先创建并刷新ObjectOutputStream。这是因为ObjectInputStream在继续操作之前先读取OOS发送的标头。

  • 本文向大家介绍什么是线程死锁?如何避免死锁?相关面试题,主要包含被问及什么是线程死锁?如何避免死锁?时的应答技巧和注意事项,需要的朋友参考一下 认识线程死锁 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态

  • 问题内容: 我已升级到最新的Java 7 build 1.7.0_60-b19,但问题仍然存在。 我进行了另一个线程转储,发现了相同的问题:在DefaultCorrelatingMessageHandler锁调用中,所有DefaultMessageListenerContainers(计数为20)都由taskScheduler(entityScheduler-3)锁定。 这是调度程序和聚合器配置: