java 死锁如何排查_记一次Java项目死锁问题的排查思路

为了提升项目的响应速度,为用户提供更好的体验,原来的DAO使用的是JdbcTemplate,最近开发了一个有点类似Hibernate的组件,用来支持DAO对象的缓存。在数据插入和数据删除时,多次使用锁,有CLH自旋锁和ReentrantReadWriteLock读写锁。设计的时候就觉得,多线程下逻辑有点复杂,很可能会发生死锁,开发完成后进行测试,多线程同时进行查询、插入和删除操作,在测试程序执行了1个小时左右时,果然出现了请求未响应、响应处理慢的情况。

首先要做的是判断问题是否由于死锁导致:

请求没有响应,处理慢,很有可能是处理线程被阻塞,或者是发生未捕获的异常导致线程直接挂掉。开发时候有在自旋锁上增加异常警告日志,如果自旋时间过长,则会打印日志。查看日志信息:

aa169dd3c1cdb7e6ea10e57ef366d15d.png

果然打印了此日志,那么就有理由怀疑是死锁导致的了。

接下来是定位死锁发生的位置:

第一种可以使用jamp命令生成dump文件(以前发过的:使用mat工具分析内存占用 或百度用法)。因为我debug是用的idea,所以这里使用的是第二种方法:直接在idea中,分析dump。

2717f633e44cd16ae2b21b548d575870.png

de8f4c9c248b3904b9f9ddacb4b60e36.png

接下来,找到请求处理线程,查看对应的调用栈信息。尤其要关注WAIT状态和RUNNING状态的(WAIT状态大概率是读写锁,而自旋锁会占用CPU,RUNNING状态下的也能是自旋锁)。如下:

3af620f37ccaaea8497b7878c2647641.png

然后像下图这样将所有由于锁导致等待的线程的加锁过程列出来,可以更清楚的分析是哪里可能发生死锁,哪里可以去优化。

90c5c5f73dcec8e1c9024926ea085a00.png

这里很容易就看出了是删除和插入操作在并发时可能导致死锁。修复代码bug完善逻辑,死锁的问题得以解决。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值