持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情
大家好,我是尚影嫣🌷,一名Java后端程序媛。如果您喜欢我的文章,欢迎点赞➕关注❤️,让我们一起成为更好的我们~
线程的死锁
线程死锁是指:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。死锁后不会出现异常,不会出现提示,由于线程被无限期地阻塞,因此程序无法正常终止。
产生死锁的四个必要条件
1)互斥条件:一个资源每次只能被一个进程使用。
2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3)不剥夺条件:进程已获得的资源,在末使用完之前不能强行剥夺。
4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
处理死锁的方法
预防死锁;避免死锁;检测死锁;解除死锁。
如何避免线程死锁?
- 破坏请求与保持条件 :一次性申请所有的资源。
- 破坏不剥夺条件 :占用部分资源的线程在进一步申请其他资源时,如果没申请成功,可以主动释放它占有的资源。
- 破坏循环等待条件 :靠按序申请资源来预防,破坏循环等待条件。
死锁示例:
package yanf.thread;
public class Deadlock {
public static void main(String[] args) {
Culprit c = new Culprit();
Police p = new Police();
new MyThread(c, p).start();
}
static class MyThread extends Thread {
private Culprit c;
private Police p;
public MyThread(Culprit c, Police p) {
this.c = c;
this.p = p;
}
@Override
public void run() {
p.say(c);
}
}
static class Culprit {
public void say(Police p) {
System.out.println("罪犯:你放了我,我放了人质!");
p.response();
}
public void response() {
System.out.println("罪犯被放走了,罪犯也放了人质");
}
}
static class Police {
public void say(Culprit c) {
System.out.println("警察:你放了人质,我放了你!");
c.response();
}
public void response() {
System.out.println("罪犯放了人质,罪犯逃走了");
}
}
}
运行结果: