死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉则它们都无法推进下去。如果系统资源充足,进程的资源请求都能得到满足,死锁出现的可能性会降低,否则就会因为争夺有限的资源而陷入死锁。

JUC 死锁编码/分析 - 图1

测试案例

  1. package com.binfoo.deadedlock;
  2. import java.util.concurrent.TimeUnit;
  3. public class LockTest {
  4. public static void main(String[] args) {
  5. Dead dead = new Dead();
  6. new Thread(dead::A, "1").start();
  7. new Thread(dead::B, "2").start();
  8. }
  9. }
  10. class Dead {
  11. final Object a = new Object();
  12. final Object b = new Object();
  13. public void A() {
  14. synchronized (a) {
  15. System.out.println(Thread.currentThread().getName() + "持有 a 锁");
  16. try {
  17. TimeUnit.SECONDS.sleep(2);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. synchronized (b) {
  22. System.out.println(Thread.currentThread().getName() + "持有 b 锁");
  23. }
  24. }
  25. }
  26. public void B() {
  27. synchronized (b) {
  28. System.out.println(Thread.currentThread().getName() + "持有 b 锁");
  29. try {
  30. TimeUnit.SECONDS.sleep(2);
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. synchronized (a) {
  35. System.out.println(Thread.currentThread().getName() + "持有 a 锁");
  36. }
  37. }
  38. }
  39. }

运行结果如下。

  1. jps -l
  2. jstack

image.png

产生原因

系统资源不足
进程运行推进的顺序不合适
资源分配不当

参考资料

JUC_死锁原因与定位分析