java线程死锁(deadlock)是什么 死锁4个条件上厕所也能解释?
程序员文章站
2022-05-22 11:20:57
...
java线程死锁(deadlock)是什么?
多线程在带来高效的处理速度时还带来一系列的问题,死锁就是其中之一,
死锁:就是两个即以上的线程因为某种关系造成双方都无法继续下去的原因,例如A需要B,B需要A
例如:程序员去面试需要工作经验,但是只有面试了才能有工作经验就会陷入一种窘迫的场景
又或者程序员在带薪上厕所没带纸,需要同事手里的纸但是同事得去厕所才能给他 并且厕所只能容纳一个人因此另一个同事上不了厕所,里面的同事业出不来:)
死锁的产生有4的必要的条件
- 互斥条件:一个资源每次只能被一个进程使用,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
- 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。
- 循环等待条件: 若干进程间形成首尾相接循环等待资源的关系
如果发生了死锁必然会有上述条件,但凡有一个不成立就不会产生
例如上面的例子:
- 厕所 纸巾 == 资源 人 == 线程
- 厕所只能一个人用 == 互斥条件
- 上厕所的人想要纸但是不想没擦pp就出来 == 请求与保持条件
- 上厕所到一半不能被其他人给拉出来 == 不可剥夺条件
- 外面的人要上厕所,里面的人要等纸才能出来 == 循环等待条件
接下去就是手撸一个死锁案例
public static void main(String[] args) {
Object paper = new Object();
Object toilet = new Object();
new Thread(()->{
synchronized (toilet){
System.out.println("我在上厕所"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (paper){
System.out.println("拿到纸,我可以出去了"+Thread.currentThread().getName());
}
}
},"上厕所的人").start();
new Thread(()->{
synchronized (paper){
System.out.println("我有纸现在");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (toilet){
System.out.println("我在上厕所了"+Thread.currentThread().getName());
}
}
},"有纸的同事").start();
}
结果就是里面的人出不来,外面的人进不去
上一篇: Java多线程:线程的同步与死锁
下一篇: PAT//迪杰特斯拉算法