一、概述

两个或两个以上的进程在执行任务的过程中,因争抢资源而造成的一种互相等待的现象,若无外力干涉将无法推进下去。

二、死锁演示

  1. public class HoldLockThread implements Runnable {
  2. private String lock1;
  3. private String lock2;
  4. public HoldLockThread(String lock1, String lock2) {
  5. this.lock1 = lock1;
  6. this.lock2 = lock2;
  7. }
  8. // A线程进来获得锁A,(等2s)然后B线程进来获得锁B,然后A想去获得锁B(此时B还持有锁B)
  9. @Override
  10. public void run() {
  11. synchronized (lock1) {
  12. System.out.println(Thread.currentThread().getName() + "\t自己持有lock1:" + lock1 + ",尝试获得lock2:" + lock2);
  13. try {
  14. // 等待两秒,让第二B线程启动并获取锁B
  15. TimeUnit.SECONDS.sleep(2);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. synchronized (lock2) {
  20. System.out.println(Thread.currentThread().getName() + "\t自己持有lock2:" + lock2 + ",尝试获得lock1:" + lock1);
  21. }
  22. }
  23. }
  24. }
  1. public class DeadLockDemo {
  2. public static void main(String[] args) {
  3. String lockA = "lockA";
  4. String lockB = "lockB";
  5. new Thread(new HoldLockThread(lockA,lockB),"ThreadAAA").start();
  6. new Thread(new HoldLockThread(lockB,lockA),"ThreadBBB").start();
  7. }
  8. }

1、上述代码就会出现死锁,A线程进来获得锁A,(等2s)然后B线程进来获得锁B,然后A想去获得锁B(此时B还持有锁B)。
2、首先通过jps命令定位进程号,可以看到DeadLockDemo正在运行,进程号是54760

  1. superking@wangchaodeMacBook-Pro examination % jps -l
  2. 54835 jdk.jcmd/sun.tools.jps.Jps
  3. 54708 org.jetbrains.idea.maven.server.RemoteMavenServer36
  4. 54758 org.jetbrains.jps.cmdline.Launcher
  5. 54760 com.supkingx.base.f_thread.deadlock.DeadLockDemo

3、通过jstack分析问题。

  1. superking@wangchaodeMacBook-Pro examination % jstack 54760
  2. 2021-10-17 10:45:26
  3. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode):
  4. "Attach Listener" #14 daemon prio=9 os_prio=31 tid=0x00007fb823810000 nid=0xa703 waiting on condition [0x0000000000000000]
  5. java.lang.Thread.State: RUNNABLE
  6. "DestroyJavaVM" #13 prio=5 os_prio=31 tid=0x00007fb824080000 nid=0xe03 waiting on condition [0x0000000000000000]
  7. java.lang.Thread.State: RUNNABLE
  8. "ThreadBBB" #12 prio=5 os_prio=31 tid=0x00007fb82980a000 nid=0xa803 waiting for monitor entry [0x0000700004e87000]
  9. java.lang.Thread.State: BLOCKED (on object monitor)
  10. at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
  11. - waiting to lock <0x000000076ac231d0> (a java.lang.String)
  12. - locked <0x000000076ac23208> (a java.lang.String)
  13. at java.lang.Thread.run(Thread.java:748)
  14. "ThreadAAA" #11 prio=5 os_prio=31 tid=0x00007fb82407f000 nid=0x5a03 waiting for monitor entry [0x0000700004d84000]
  15. java.lang.Thread.State: BLOCKED (on object monitor)
  16. at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
  17. - waiting to lock <0x000000076ac23208> (a java.lang.String)
  18. - locked <0x000000076ac231d0> (a java.lang.String)
  19. at java.lang.Thread.run(Thread.java:748)
  20. "Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007fb825819800 nid=0xa903 runnable [0x0000000000000000]
  21. java.lang.Thread.State: RUNNABLE
  22. "C1 CompilerThread3" #9 daemon prio=9 os_prio=31 tid=0x00007fb82402e800 nid=0x5503 waiting on condition [0x0000000000000000]
  23. java.lang.Thread.State: RUNNABLE
  24. "C2 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007fb82402d800 nid=0x3d03 waiting on condition [0x0000000000000000]
  25. java.lang.Thread.State: RUNNABLE
  26. "C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007fb82505b800 nid=0x3e03 waiting on condition [0x0000000000000000]
  27. java.lang.Thread.State: RUNNABLE
  28. "C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007fb82505b000 nid=0x4003 waiting on condition [0x0000000000000000]
  29. java.lang.Thread.State: RUNNABLE
  30. "Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007fb82606c800 nid=0x3a03 runnable [0x000070000466f000]
  31. java.lang.Thread.State: RUNNABLE
  32. at java.net.SocketInputStream.socketRead0(Native Method)
  33. at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
  34. at java.net.SocketInputStream.read(SocketInputStream.java:171)
  35. at java.net.SocketInputStream.read(SocketInputStream.java:141)
  36. at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
  37. at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
  38. at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
  39. - locked <0x000000076ac83cc0> (a java.io.InputStreamReader)
  40. at java.io.InputStreamReader.read(InputStreamReader.java:184)
  41. at java.io.BufferedReader.fill(BufferedReader.java:161)
  42. at java.io.BufferedReader.readLine(BufferedReader.java:324)
  43. - locked <0x000000076ac83cc0> (a java.io.InputStreamReader)
  44. at java.io.BufferedReader.readLine(BufferedReader.java:389)
  45. at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:47)
  46. "Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fb82500d000 nid=0x3903 runnable [0x0000000000000000]
  47. java.lang.Thread.State: RUNNABLE
  48. "Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fb82402d000 nid=0x4d03 in Object.wait() [0x0000700004363000]
  49. java.lang.Thread.State: WAITING (on object monitor)
  50. at java.lang.Object.wait(Native Method)
  51. - waiting on <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)
  52. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
  53. - locked <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)
  54. at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
  55. at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
  56. "Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fb825811000 nid=0x3403 in Object.wait() [0x0000700004260000]
  57. java.lang.Thread.State: WAITING (on object monitor)
  58. at java.lang.Object.wait(Native Method)
  59. - waiting on <0x000000076ab06c00> (a java.lang.ref.Reference$Lock)
  60. at java.lang.Object.wait(Object.java:502)
  61. at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
  62. - locked <0x000000076ab06c00> (a java.lang.ref.Reference$Lock)
  63. at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
  64. "VM Thread" os_prio=31 tid=0x00007fb826812800 nid=0x3303 runnable
  65. "GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fb824013000 nid=0x2207 runnable
  66. "GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fb825008800 nid=0x2103 runnable
  67. "GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fb825009000 nid=0x1f03 runnable
  68. "GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fb825808800 nid=0x2a03 runnable
  69. "GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007fb825809000 nid=0x2c03 runnable
  70. "GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007fb825809800 nid=0x5403 runnable
  71. "GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007fb82500a000 nid=0x2f03 runnable
  72. "GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007fb82500a800 nid=0x3003 runnable
  73. "GC task thread#8 (ParallelGC)" os_prio=31 tid=0x00007fb82580a000 nid=0x3103 runnable
  74. "GC task thread#9 (ParallelGC)" os_prio=31 tid=0x00007fb824014000 nid=0x5003 runnable
  75. "VM Periodic Task Thread" os_prio=31 tid=0x00007fb82a008800 nid=0x5803 waiting on condition
  76. JNI global references: 15
  77. Found one Java-level deadlock:
  78. =============================
  79. "ThreadBBB":
  80. waiting to lock monitor 0x00007fb82602b5e8 (object 0x000000076ac231d0, a java.lang.String),
  81. which is held by "ThreadAAA"
  82. "ThreadAAA":
  83. waiting to lock monitor 0x00007fb8260290c8 (object 0x000000076ac23208, a java.lang.String),
  84. which is held by "ThreadBBB"
  85. Java stack information for the threads listed above:
  86. ===================================================
  87. "ThreadBBB":
  88. at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
  89. - waiting to lock <0x000000076ac231d0> (a java.lang.String)
  90. - locked <0x000000076ac23208> (a java.lang.String)
  91. at java.lang.Thread.run(Thread.java:748)
  92. "ThreadAAA":
  93. at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
  94. - waiting to lock <0x000000076ac23208> (a java.lang.String)
  95. - locked <0x000000076ac231d0> (a java.lang.String)
  96. at java.lang.Thread.run(Thread.java:748)
  97. Found 1 deadlock.

通过上述输出结果可以看到最后一行 Found 1 deadlock.。
根据输出结果如下,出现了互相等待,即产生了死锁
image.png