123-多线程死锁分析,案例介绍
死锁。多个锁相互交叉锁定代码
当线程T1持有资源A,线程T2持有资源B。此时线程T1想要获取资源B,并且线程T2想要获取资源A。两个线程都想要获取对方手中的资源,自己又不肯让出已有资源,一直僵持不下就形成了死锁。
程序在运行时什么事都没做(不输出日志、CPU内存等都没有发生变化),此时极有可能发生了死锁。需要查看程序运行情况。
案例
线程T1:
public class DeadLock { private OtherService otherService; public void setOtherService(OtherService otherService) { this.otherService = otherService; } // DeadLock的实例的锁-资源A private final Object LOCK = new Object(); public void m1() { synchronized (LOCK) { System.out.println("********m1********"); otherService.s1(); } } public void m2() { synchronized (LOCK) { System.out.println("********m2********"); } } }
线程T2:
public class OtherService { private DeadLock deadLock; public void setDeadLock(DeadLock deadLock) { this.deadLock = deadLock; } // OtherService的实例的锁-资源B private final Object LOCK = new Object(); public void s1() { synchronized (LOCK) { System.out.println("========s1========"); } } public void s2() { synchronized (LOCK) { System.out.println("========s2========"); deadLock.m2(); } } }
测试调用方法:
public static void main(String[] args) { DeadLock deadLock = new DeadLock(); OtherService otherService = new OtherService(); deadLock.setOtherService(otherService); otherService.setDeadLock(deadLock); new Thread(() -> { while (true) { deadLock.m1(); } }, "T1").start(); new Thread(() -> { while (true) { otherService.s2(); } }, "T2").start(); }
查看死锁
当程序运行时产生死锁,通过代码会很难分析出死锁在哪里产生。此时应通过工具jstack查看程序运行状态。
获取程序进程id(pid)。
jps
2086 DeadLockTest 2007 KotlinCompileDaemon 2106 Jps 1194 1213 RemoteMavenServer36
查看程序运行状态。
jstack 2086
Found one Java-level deadlock: ============================= "T2": waiting to lock monitor 0x00007fe848005758 (object 0x000000076adb9730, a java.lang.Object), which is held by "T1" "T1": waiting to lock monitor 0x00007fe8480042b8 (object 0x000000076adbd6a0, a java.lang.Object), which is held by "T2" Java stack information for the threads listed above: =================================================== "T2": at com.tuyrk.chapter8.DeadLock.m2(DeadLock.java:28) - waiting to lock <0x000000076adb9730> (a java.lang.Object) at com.tuyrk.chapter8.OtherService.s2(OtherService.java:29) - locked <0x000000076adbd6a0> (a java.lang.Object) at com.tuyrk.chapter8.DeadLockTest.lambda$main$1(DeadLockTest.java:24) at com.tuyrk.chapter8.DeadLockTest$$Lambda$2/2094548358.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "T1": at com.tuyrk.chapter8.OtherService.s1(OtherService.java:22) - waiting to lock <0x000000076adbd6a0> (a java.lang.Object) at com.tuyrk.chapter8.DeadLock.m1(DeadLock.java:22) - locked <0x000000076adb9730> (a java.lang.Object) at com.tuyrk.chapter8.DeadLockTest.lambda$main$0(DeadLockTest.java:19) at com.tuyrk.chapter8.DeadLockTest$$Lambda$1/500977346.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
T2持有0x000000076adbd6a0,想要获取0x000000076adb9730;
而T1持有0x000000076adb9730,想要获取0x000000076adbd6a0。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 tuyrk@qq.com
文章标题:123-多线程死锁分析,案例介绍
文章字数:588
本文作者:神秘的小岛岛
发布时间:2019-11-30, 14:37:24
最后更新:2019-11-30, 15:25:23
原始链接:https://www.tuyrk.cn/wang-thread/123-deadlock-case/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。