真实案例:使用Java Thread Dump分析ReadWriteLock导致的死锁问题

本文通过一个真实的案例,详细分析了如何使用Java Thread Dump来诊断由Jackson-databind(版本2.4.1)引起的ReadWriteLock导致的死锁问题。当一个线程在持有写锁后陷入死循环,导致其他线程等待读锁,引发应用响应缓慢和CPU升高。通过检查Thread Dump,发现在等待读锁的线程中存在死锁迹象,进一步追踪代码发现LinkedHashMap在并发操作时可能产生循环,导致线程不安全。文章提醒开发者注意多线程环境下,使用具有修改内部状态的线程不安全数据结构可能导致的问题。
摘要由CSDN通过智能技术生成

真实案例:使用Java Thread Dump分析ReadWriteLock导致的死锁问题

本文的死锁

本文的死锁是由jackson-databind造成的,版本是2.4.1。
这里的死锁是这样的:一组线程中的某一个线程获得写锁之后无限循环,导致其他的试图获取读锁的线程无限等待,从而导致此组线程的工作无法推进。这有区别于常规的死锁定义。

表象

最近经常收到某应用(tomcat部署)无法响应用户请求的报警。在线上使用curl向问题实例发起请求,没法相应,然后使用ps发现CPU飙高。

获取Thread Dump

使用kill -3 <pid>。因为我们使用的是tomcat应用容器,tomcat会把Thread Dump打印到其安装目录下的logs/catalina.out文件里。

分析

  • 首先我们需要确认有多少线程处于WAITING状态,以及在执行什么:
    cat case/catalina.out|grep 'java.lang.Thread.State: WAITING'|wc -l

在我们的案例中,有378个线程处于WAITING状态,然后通过审查发现,有大量的tomcat nio线程在等待ReadWriteLock的读锁,如下:

"http-nio-9086-exec-40" daemon prio=10 tid=0x00007f8aa402a800 nid=0x7965 waiting on condition [0x00007f8a5ab68000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000d3643028> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSyn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值