性能测试线程死锁问题分析和定位【杭州多测师】【杭州多测师_王sir】
死锁的根本原因:
1)存在嵌套加锁
2)多个线程之间加锁(锁定对象资源)的顺序不一致
1、死锁的概念:有2个线程、一个线程锁住了资源A、又想去锁定资源B、另外一个线程锁定了资源B、又想去锁定资源A、2个线程都想
去得到对方的资源、而又不愿释放自己的的资源、从而造成了一种互相等待3、无法执行的情况
2、这个时候可以用jvisualvm或者jstack命令对线程进行dump
3、jstack 进程号 > a.log 然后在本地打开a.log 在日志的最底部发现有2个http开头的线程
4、找到 Found one Java-level deadlock: 就是找到了一个Java级别的死锁、可以看到一个线程想要锁定某个对象但是被另外一个线程锁定了
而另外一个线程想要锁定的对象被第一个线程锁定了、并且都相互没有释放
5、线程死锁之后现象:TPS几乎为0、压力测试工具无法得到服务器的响应、服务器硬件的资源CPU和内存 IO等等都是非常空闲的、通过
jvisualvm查看线程发现至少有2个线程一直处于红色的阻塞状态、死锁一般都是表现为程序停顿。
6、在查看报错的时候发现是CaseController这个类报错了、然后去看一下Java代码、发现代码里面一个锁synchronized里面又嵌套了另外一个锁
然后分析里面的代码发现、是通过random方法获取0-5之间的随机数、当随机数为0的时候拿到的对象为1和2、当随机数为3的时候、拿到的对象为1和1
7、解决的办法:
1)避免嵌套的加锁
2)减少锁粒度 ==》就是不加Thread.sleep() 或者减少代码的量也能减少死锁 ==》一般都是概率性的问题