【Java并发】死锁演示
1. 死锁代码
public class DeadLockDemo {
private static final String A = "A";
private static final String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
System.out.printf("[%s]ADD LOCK TO A%n", Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.printf("[%s]ADD LOCK TO B%n", Thread.currentThread().getName());
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B) {
System.out.printf("[%s]ADD LOCK TO B%n", Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (A) {
System.out.printf("[%s]ADD LOCK TO A%n", Thread.currentThread().getName());
}
}
}
});
t1.start();
t2.start();
}
}
2. jstack 查看死锁
使用 jps 找到对应 java 线程的 PID (这里是 DeadLockDemo 进程),再使用 jstack dump 出进程状态,查看有无处于 BLOCKED 状态的线程

3. 避免死锁的方法
- 避免一个线程同时获得多个锁
- 避免一个线程再锁内同时占用多个资源,尽量保证每一个锁只会占用一个资源
- 尝试使用定时锁,使用
lock.tryLock(timeout)来代替使用内部锁机制 - 对于数据库锁,加锁和解锁必须在同一个数据库链接里面,否则会出现解锁失败的情况
- 如果出现在锁中再加锁的情况,一定要保证不同线程之间的加锁顺序一致
浙公网安备 33010602011771号