手写死锁
# 产生死锁的条件
一般来说,要出现死锁问题需要满足以下条件:
- 互斥条件:一个资源每次只能被一个线程使用。
- 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。
- 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
# 手写死锁例子
//可能发生静态锁顺序死锁的代码
class StaticLockOrderDeadLock {
private final Object lockA = new Object();
private final Object lockB = new Object();
public void a() {
synchronized (lockA) {
synchronized (lockB) {
System.out.println("function a");
}
}
}
public void b() {
synchronized (lockB) {
synchronized (lockA) {
System.out.println("function b");
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- a和b两个方法都需要获得A锁和B锁。一个线程执行a方法且已经获得了A锁,在等待B锁;
- 另一个线程执行了b方法且已经获得了B锁,在等待A锁。
这种状态,就是发生了静态的锁顺序死锁。
解决办法: 所有需要多个锁的线程,都要以相同的顺序来获得锁。
//正确的代码
class StaticLockOrderDeadLock {
private final Object lockA = new Object();
private final Object lockB = new Object();
public void a() {
synchronized (lockA) {
synchronized (lockB) {
System.out.println("function a");
}
}
}
public void b() {
synchronized (lockA) {
synchronized (lockB) {
System.out.println("function b");
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编辑 (opens new window)
上次更新: 2022/05/19, 21:26:01