@[toc]
什麼是多線程死鎖?
同步中嵌套同步,導緻鎖無法釋放
多線程以及多程序改善了系統資源的使用率并提高了系統 的處理能力。然而,并發執行也帶來了新的問題——死鎖。所謂死鎖是指多個線程因競争資源而造成的一種僵局(互相等待),若無外力作用,這些程序都将無法向前推進。
1、系統資源的競争
通常系統中擁有的不可剝奪資源,其數量不足以滿足多個程序運作的需要,使得程序在運作過程中,會因争奪資源而陷入僵局,如錄音帶機、列印機等。隻有對不可剝奪資源的競争才可能産生死鎖,對可剝奪資源的競争是不會引起死鎖的。
2、程序推進順序不合适
程序在運作過程中,請求和釋放資源的順序不當,也同樣會導緻死鎖。例如,并發程序 P1、P2分别保持了資源R1、R2,而程序P1申請資源R2,程序P2申請資源R1時,兩者都會因為所需資源被占用而阻塞。
package com.yxl.demo.ThreadTest;
public class test5 {
public static void main(String[] args) throws InterruptedException {
TestDemo thread = new TestDemo();
Thread t1 = new Thread(thread,"視窗一");
Thread t2 = new Thread(thread,"視窗二");
t1.start();
Thread.sleep(40);
thread.flag = false;
t2.start();
}
}
class TestDemo implements Runnable{
//共享的火車票變量
private volatile int count = 100;
private Object object =new Object();
boolean flag = true;
//重寫run方法
@Override
public void run() {
if(flag){
while (count > 0) {
synchronized (object) {
sale();
}
}
}else{
while (count > 0) {
sale();
}
}
}
public synchronized void sale() {
try {
Thread.sleep(50);
}catch (Exception e){
}
synchronized (object) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "出售 :" + (100 - count + 1));
count--;
}
}
}
/*
public void sale(){
synchronized (object){
if(count > 0){
System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
count--;
}
}
}*/
}
執行結果:如圖所示,紅燈一直亮着,鎖一直沒釋放,導緻死鎖的發生,程式卡住
t1 先擷取object鎖,在擷取this鎖,
t2 先擷取this鎖 ,在擷取object鎖
如何解決死鎖的發生
- 加鎖順序(線程按照一定的順序加鎖)
- 加鎖時限(線程嘗試擷取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,并釋放自己占有的鎖)
- 死鎖檢測