死锁总结

分析死锁形成的原理,与避免死锁的方法。


死锁的形成原理

先用一段代码来模拟死锁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";

public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(A) {
try {
Thread.currentThread().sleep(2000);
} catch (interruptedException e) {
e.printStackTrace();
}
synchronized(B) {
System.out.println("t1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(B) {
synchronized(A) {
System.out.println("t2");
}
}
}
});
t1.start();
t2.start();
}
}

上面的代码t1线程锁定资源A,然后睡眠2秒后需要锁定资源B才能结束运行,t2线程直接锁定了资源B,然后需要锁定资源A才能结束运行,由于两个线程都无法拿到需要的资源,所以都处于阻塞状态。

避免死锁的方法

  1. 避免一个线程同时获取多个锁。
  2. 避免一个线程在锁内同时占用多个资源,尽量保证每个锁子占用一个资源。
  3. 使用定时锁lock.tryLock(timeout)来代替内部锁机制。
  4. 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。