hbf548

多看源码多读书

0%

死锁

概念

多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形.。某一个同步块同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题.​

总而言之就是:多个线程互相抱着对方需要的资源,然后形成僵持

案例:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0,"灰姑娘");
Makeup g2 = new Makeup(1,"白雪公主");

g1.start();
g2.start();
}
}

//口红
class Lipstick{

}

//镜子
class Mirror{

}

class Makeup extends Thread{

//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();

int chioce;//选择
String girlName; //使用化妆品的人


public Makeup(int chioce, String girlName){
this.chioce = chioce;
this.girlName = girlName;

}

@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

//化妆,互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (chioce == 0){
synchronized (lipstick){ //获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);//1秒后获得镜子的锁
synchronized (mirror){ //获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
}
}
}else {
synchronized (mirror){ //获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);
synchronized (lipstick){ //获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
}

image.png
发现程序卡死了,死锁!原因很简单:
灰姑娘 和 白雪公主都需要对方的支援来释放锁,互相不谦让,导致死锁。

解决方法

那就是两个人不要去抱对方的锁就行了,这样就有一个人先释放资源,从而解决死锁

image.png


产生死锁的条件

产生死锁的四个必要条件:

  1. 互斥条件: 一个资源每次只能被一个进程使用。
  2. 请求与保持条件: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件 :进程已获得的资源,在末使用完之前,不能强行剥夺。
  4. 循环等待条件 :若干进程之间形成一种头尾相接的循环等待资源关系。

上面列出了死锁的四个必要条件,我们只要想办法破其中的任意一个或多个条件就可以避免死锁发生!