# 如何写出一个 Java 死锁程序以及分析jstack ## 一、什么是死锁 死锁(Deadlock)是指两个或多个线程在执行过程中,因争夺资源而造成的一种互相等待的现象。当多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,导致这些线程无限期地阻塞下去。 死锁的四个必要条件: 1. **互斥条件**:资源一次只能由一个线程占用 2. **请求与保持条件**:线程持有至少一个资源,并等待获取其他资源 3. **不剥夺条件**:已分配给线程的资源不能被其他线程强行夺取 4. **循环等待条件**:存在一个线程的循环等待链 ## 二、编写Java死锁程序 下面是一个简单的Java死锁示例程序: ```java public class DeadlockDemo { private static final Object lock1 = new Object(); private static final Object lock2 = new Object(); public static void main(String[] args) { Thread threadA = new Thread(() -> { synchronized (lock1) { System.out.println("ThreadA holding lock1..."); try { Thread.sleep(100); // 模拟业务处理 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("ThreadA waiting for lock2..."); synchronized (lock2) { System.out.println("ThreadA holding lock1 and lock2..."); } } }); Thread threadB = new Thread(() -> { synchronized (lock2) { System.out.println("ThreadB holding lock2..."); try { Thread.sleep(100); // 模拟业务处理 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("ThreadB waiting for lock1..."); synchronized (lock1) { System.out.println("ThreadB holding lock2 and lock1..."); } } }); threadA.start(); threadB.start(); } }
运行上述程序后,控制台输出可能会卡在类似以下状态:
ThreadA holding lock1... ThreadB holding lock2... ThreadA waiting for lock2... ThreadB waiting for lock1...
程序不会终止,因为两个线程互相持有对方需要的锁,形成了死锁。
jstack是JDK自带的一个命令行工具,用于生成Java虚拟机当前时刻的线程快照(thread dump)。
首先使用jps
命令查找Java进程的PID:
jps -l
使用jstack命令生成线程转储:
jstack -l <PID> > deadlock.log
打开生成的deadlock.log文件,搜索”deadlock”或”Found one Java-level deadlock”,可以看到类似以下内容:
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007f8b381062b8 (object 0x000000076ab270c0, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007f8b38107318 (object 0x000000076ab270d0, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at DeadlockDemo.lambda$main$1(DeadlockDemo.java:28) - waiting to lock <0x000000076ab270c0> (a java.lang.Object) - locked <0x000000076ab270d0> (a java.lang.Object) "Thread-0": at DeadlockDemo.lambda$main$0(DeadlockDemo.java:14) - waiting to lock <0x000000076ab270d0> (a java.lang.Object) - locked <0x000000076ab270c0> (a java.lang.Object)
tryLock()
)ConcurrentHashMap
、CountDownLatch
等通过理解死锁原理、编写示例程序和使用jstack工具分析,我们可以更好地识别和解决Java程序中的死锁问题。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。