1. 什麼是多線程死鎖?
同步中嵌套同步,導致鎖無法釋放
多線程以及多進程改善了系統資源的利用率並提高了系統 的處理能力。然而,併發執行也帶來了新的問題——死鎖。所謂死鎖是指多個線程因競爭資源而造成的一種僵局(互相等待),若無外力作用,這些進程都將無法向前推進。
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鎖
2. 如何解決死鎖的發生
- 加鎖順序(線程按照一定的順序加鎖)
- 加鎖時限(線程嘗試獲取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,並釋放自己佔有的鎖)
- 死鎖檢測