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();
}
結果就是裏面的人出不來,外面的人進不去