1、死锁例子

代码例子

  1. public class Main {
  2. public static String obj1 = "obj1";
  3. public static String obj2 = "obj2";
  4. public static void main(String[] args) {
  5. LockA la = new LockA();
  6. Thread threadA = new Thread(la);
  7. threadA.start();
  8. LockB lb = new LockB();
  9. Thread threadB = new Thread(lb);
  10. threadB.start();
  11. try {
  12. Thread.sleep(5000);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. // 此时两个线程都出BLOCKED状态
  17. // BLOCKED
  18. System.out.println(threadA.getState());
  19. // BLOCKED
  20. System.out.println(threadB.getState());
  21. }
  22. }
  23. class LockA implements Runnable{
  24. public void run() {
  25. try {
  26. System.out.println(System.currentTimeMillis() + " LockA 开始执行");
  27. while(true){
  28. synchronized (Main.obj1) {
  29. System.out.println(System.currentTimeMillis() + " LockA 锁住 obj1");
  30. Thread.sleep(3000); // 此处等待是给B能锁住机会
  31. synchronized (Main.obj2) {
  32. System.out.println(System.currentTimeMillis() + " LockA 锁住 obj2");
  33. Thread.sleep(60 * 1000); // 为测试,占用了就不放
  34. }
  35. }
  36. }
  37. } catch (Exception e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. }
  42. class LockB implements Runnable{
  43. public void run() {
  44. try {
  45. System.out.println(System.currentTimeMillis() + " LockB 开始执行");
  46. while(true){
  47. System.out.println(System.currentTimeMillis() + " LockB 锁住 obj2");
  48. synchronized (Main.obj2) {
  49. System.out.println(System.currentTimeMillis() + " LockB 锁住 obj2");
  50. Thread.sleep(3000); // 此处等待是给A能锁住机会
  51. synchronized (Main.obj1) {
  52. System.out.println(System.currentTimeMillis() + " LockB 锁住 obj1");
  53. Thread.sleep(60 * 1000); // 为测试,占用了就不放
  54. }
  55. }
  56. }
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. }

堆栈排查死锁

  • IDEA左边有个相机的图标,可以打印堆栈信息

image.png

  • 日志分析结果,deadlock死锁关键字
    • Thread-1:持有一个String锁d0,等待获取另一个String锁a0
    • Thread-0:持有一个String锁a0,等待获取另一个String锁d0
    • 两个线程持有一个锁,再去尝试获取对方持有的锁

      Found one Java-level deadlock:

      “Thread-1”:

waiting to lock monitor 0x00000206d33fef48 (object 0x000000076b4100a0, a java.lang.String),

which is held by “Thread-0”

“Thread-0”:

waiting to lock monitor 0x00000206d33fede8 (object 0x000000076b4100d0, a java.lang.String),

which is held by “Thread-1”

Java stack information for the threads listed above:

===================================================

“Thread-1”:

  1. at com.wangchun.LockB.run(Main.java:56)
  2. - waiting to lock <0x000000076b4100a0> (a java.lang.String)
  3. - locked <0x000000076b4100d0> (a java.lang.String)
  4. at java.lang.Thread.run(Thread.java:748)

“Thread-0”:

  1. at com.wangchun.LockA.run(Main.java:37)
  2. - waiting to lock <0x000000076b4100d0> (a java.lang.String)
  3. - locked <0x000000076b4100a0> (a java.lang.String)
  4. at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

  1. 2021-08-24 00:13:38
  2. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.271-b09 mixed mode):
  3. "DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x00000206b86c7000 nid=0x1b68 waiting on condition [0x0000000000000000]
  4. java.lang.Thread.State: RUNNABLE
  5. "Thread-1" #13 prio=5 os_prio=0 tid=0x00000206d5948000 nid=0x16d8 waiting for monitor entry [0x000000dc6bdfe000]
  6. java.lang.Thread.State: BLOCKED (on object monitor)
  7. at com.wangchun.LockB.run(Main.java:56)
  8. - waiting to lock <0x000000076b4100a0> (a java.lang.String)
  9. - locked <0x000000076b4100d0> (a java.lang.String)
  10. at java.lang.Thread.run(Thread.java:748)
  11. "Thread-0" #12 prio=5 os_prio=0 tid=0x00000206d5940000 nid=0x33f4 waiting for monitor entry [0x000000dc6bcfe000]
  12. java.lang.Thread.State: BLOCKED (on object monitor)
  13. at com.wangchun.LockA.run(Main.java:37)
  14. - waiting to lock <0x000000076b4100d0> (a java.lang.String)
  15. - locked <0x000000076b4100a0> (a java.lang.String)
  16. at java.lang.Thread.run(Thread.java:748)
  17. "Service Thread" #11 daemon prio=9 os_prio=0 tid=0x00000206d5939800 nid=0x3e04 runnable [0x0000000000000000]
  18. java.lang.Thread.State: RUNNABLE
  19. "C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x00000206d586e800 nid=0x3364 waiting on condition [0x0000000000000000]
  20. java.lang.Thread.State: RUNNABLE
  21. "C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x00000206d586a800 nid=0x3b4 waiting on condition [0x0000000000000000]
  22. java.lang.Thread.State: RUNNABLE
  23. "C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x00000206d586a000 nid=0x270 waiting on condition [0x0000000000000000]
  24. java.lang.Thread.State: RUNNABLE
  25. "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x00000206d5867000 nid=0x1d10 waiting on condition [0x0000000000000000]
  26. java.lang.Thread.State: RUNNABLE
  27. "Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x00000206d5864800 nid=0x2e80 runnable [0x000000dc6b5fe000]
  28. java.lang.Thread.State: RUNNABLE
  29. at java.net.SocketInputStream.socketRead0(Native Method)
  30. at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
  31. at java.net.SocketInputStream.read(SocketInputStream.java:171)
  32. at java.net.SocketInputStream.read(SocketInputStream.java:141)
  33. at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
  34. at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
  35. at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
  36. - locked <0x000000076b3120a8> (a java.io.InputStreamReader)
  37. at java.io.InputStreamReader.read(InputStreamReader.java:184)
  38. at java.io.BufferedReader.fill(BufferedReader.java:161)
  39. at java.io.BufferedReader.readLine(BufferedReader.java:324)
  40. - locked <0x000000076b3120a8> (a java.io.InputStreamReader)
  41. at java.io.BufferedReader.readLine(BufferedReader.java:389)
  42. at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:49)
  43. "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000206d3432800 nid=0x1118 runnable [0x0000000000000000]
  44. java.lang.Thread.State: RUNNABLE
  45. "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000206d342f800 nid=0x3c18 waiting on condition [0x0000000000000000]
  46. java.lang.Thread.State: RUNNABLE
  47. "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000206d33ff800 nid=0x3cfc in Object.wait() [0x000000dc6b2fe000]
  48. java.lang.Thread.State: WAITING (on object monitor)
  49. at java.lang.Object.wait(Native Method)
  50. - waiting on <0x000000076b188ee0> (a java.lang.ref.ReferenceQueue$Lock)
  51. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
  52. - locked <0x000000076b188ee0> (a java.lang.ref.ReferenceQueue$Lock)
  53. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
  54. at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
  55. "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000206d33f8800 nid=0x5dc in Object.wait() [0x000000dc6b1ff000]
  56. java.lang.Thread.State: WAITING (on object monitor)
  57. at java.lang.Object.wait(Native Method)
  58. - waiting on <0x000000076b186c00> (a java.lang.ref.Reference$Lock)
  59. at java.lang.Object.wait(Object.java:502)
  60. at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
  61. - locked <0x000000076b186c00> (a java.lang.ref.Reference$Lock)
  62. at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
  63. "VM Thread" os_prio=2 tid=0x00000206d33cf000 nid=0x2214 runnable
  64. "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000206b86e1000 nid=0x2850 runnable
  65. "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000206b86e2000 nid=0x1614 runnable
  66. "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000206b86e3800 nid=0x2178 runnable
  67. "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000206b86e5800 nid=0x308c runnable
  68. "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00000206b86e6800 nid=0x375c runnable
  69. "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00000206b86e7800 nid=0x1fe8 runnable
  70. "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00000206b86ea800 nid=0x3f74 runnable
  71. "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000206b86eb800 nid=0x288c runnable
  72. "GC task thread#8 (ParallelGC)" os_prio=0 tid=0x00000206b86ec800 nid=0x2350 runnable
  73. "GC task thread#9 (ParallelGC)" os_prio=0 tid=0x00000206b86ed800 nid=0x1fb0 runnable
  74. "VM Periodic Task Thread" os_prio=2 tid=0x00000206d593e000 nid=0x3a34 waiting on condition
  75. JNI global references: 12
  76. Found one Java-level deadlock:
  77. =============================
  78. "Thread-1":
  79. waiting to lock monitor 0x00000206d33fef48 (object 0x000000076b4100a0, a java.lang.String),
  80. which is held by "Thread-0"
  81. "Thread-0":
  82. waiting to lock monitor 0x00000206d33fede8 (object 0x000000076b4100d0, a java.lang.String),
  83. which is held by "Thread-1"
  84. Java stack information for the threads listed above:
  85. ===================================================
  86. "Thread-1":
  87. at com.wangchun.LockB.run(Main.java:56)
  88. - waiting to lock <0x000000076b4100a0> (a java.lang.String)
  89. - locked <0x000000076b4100d0> (a java.lang.String)
  90. at java.lang.Thread.run(Thread.java:748)
  91. "Thread-0":
  92. at com.wangchun.LockA.run(Main.java:37)
  93. - waiting to lock <0x000000076b4100d0> (a java.lang.String)
  94. - locked <0x000000076b4100a0> (a java.lang.String)
  95. at java.lang.Thread.run(Thread.java:748)
  96. Found 1 deadlock.
  97. Heap
  98. PSYoungGen total 76288K, used 10486K [0x000000076b180000, 0x0000000770680000, 0x00000007c0000000)
  99. eden space 65536K, 16% used [0x000000076b180000,0x000000076bbbd950,0x000000076f180000)
  100. from space 10752K, 0% used [0x000000076fc00000,0x000000076fc00000,0x0000000770680000)
  101. to space 10752K, 0% used [0x000000076f180000,0x000000076f180000,0x000000076fc00000)
  102. ParOldGen total 175104K, used 0K [0x00000006c1400000, 0x00000006cbf00000, 0x000000076b180000)
  103. object space 175104K, 0% used [0x00000006c1400000,0x00000006c1400000,0x00000006cbf00000)
  104. Metaspace used 3306K, capacity 4564K, committed 4864K, reserved 1056768K
  105. class space used 361K, capacity 388K, committed 512K, reserved 1048576K