死鎖:兩個(gè)或多個(gè)線程互相持有對(duì)方需要的鎖而導(dǎo)致這些線程全部處于永久阻塞狀態(tài)燥狰。如:線程A持有對(duì)象1的鎖圈驼,等待對(duì)象2的鎖;線程B持有對(duì)象2的鎖隐圾,等待對(duì)象1的鎖伍掀。
死鎖產(chǎn)生的條件:
1、互斥條件:資源不能被共享翎承,只能由一個(gè)進(jìn)程使用
2硕盹、請(qǐng)求與保持條件:進(jìn)程已獲得了一些資源符匾,但因請(qǐng)求其它資源被阻塞時(shí)叨咖,對(duì)已獲得的資源保持不放。
3、不可搶占條件(No pre-emption) :有些系統(tǒng)資源是不可搶占的甸各,當(dāng)某個(gè)進(jìn)程已獲得這種資源后垛贤,系統(tǒng)不能強(qiáng)行收回,只能由進(jìn)程使用完時(shí)自己釋放趣倾。
4聘惦、循環(huán)等待條件(Circular wait) :若干個(gè)進(jìn)程形成環(huán)形鏈,每個(gè)都占用對(duì)方申請(qǐng)的下一個(gè)資源儒恋。
code:
public class DeadLock implements Runnable{
//注意善绎,這里需要定義為static,否則t1和t2兩個(gè)線程中的o1,o2均為新創(chuàng)建的诫尽,也就是此o1非彼o1禀酱,o2也一樣,即不存在資源沖突牧嫉,不會(huì)發(fā)生死鎖剂跟。字符串除外,因?yàn)橛凶址? private static Object o1=new Object();
private static Object o2=new Object();
private int flag;
public DeadLock(int flag){
this.flag=flag;
}
@Override
public void run() {
if(flag==0){
synchronized (o1){
System.out.println("t1 Get the lock of o1");
try{
Thread.sleep(1000);
}
catch (InterruptedException ex){
ex.printStackTrace();
}
synchronized (o2){
System.out.println("t1 Get the lock of o2");
}
}
}
else{
synchronized (o2){
System.out.println("t2 Get the lock of o2");
try{
Thread.sleep(1000);
}
catch (InterruptedException ex){
ex.printStackTrace();
}
synchronized (o1){
System.out.println("t2 Get the lock of o1");
}
}
}
}
public static void main(String[]args){
DeadLock D1=new DeadLock(0);
DeadLock D2=new DeadLock(1);
Thread t1=new Thread(D1);
Thread t2=new Thread(D2);
t1.start();
t2.start();
}
}
解決死鎖的三種方案:
1.資源排序
如上訴代碼中將else{}中的o1和o2調(diào)換順序即可酣藻。
2.加鎖時(shí)限
如果一個(gè)線程沒(méi)有在指定的時(shí)間期限內(nèi)獲取到鎖曹洽,則結(jié)束當(dāng)前線程并釋放掉已獲得的鎖。終止線程的方法:stop()會(huì)釋放掉鎖但易導(dǎo)致數(shù)據(jù)不一致辽剧。suspend()終止線程但不會(huì)釋放掉鎖送淆。
3.死鎖檢測(cè)
處理死鎖的方法:
1、鴕鳥(niǎo)算法:
2怕轿、銀行家算法:
所謂銀行家算法坊夫,是指在分配資源之前先看清楚,資源分配后是否會(huì)導(dǎo)致系統(tǒng)死鎖撤卢。如果會(huì)死鎖环凿,則不分配,否則就分配放吩。
按照銀行家算法的思想智听,當(dāng)進(jìn)程請(qǐng)求資源時(shí),系統(tǒng)將按如下原則分配系統(tǒng)資源:
解決死鎖的策略
對(duì)待死鎖的策略主要有:
(1) 死鎖預(yù)防:破壞導(dǎo)致死鎖必要條件中的任意一個(gè)就可以預(yù)防死鎖渡紫。例如到推,要求用戶申請(qǐng)資源時(shí)一次性申請(qǐng)所需要的全部資源,這就破壞了保持和等待條件惕澎;將資源分層莉测,得到上一層資源后,才能夠申請(qǐng)下一層資源唧喉,它破壞了環(huán)路等待條件捣卤。預(yù)防通常會(huì)降低系統(tǒng)的效率忍抽。
(2) 死鎖避免:避免是指進(jìn)程在每次申請(qǐng)資源時(shí)判斷這些操作是否安全,例如董朝,使用銀行家算法鸠项。死鎖避免算法的執(zhí)行會(huì)增加系統(tǒng)的開(kāi)銷(xiāo)。
(3) 死鎖檢測(cè):死鎖預(yù)防和避免都是事前措施子姜,而死鎖的檢測(cè)則是判斷系統(tǒng)是否處于死鎖狀態(tài)祟绊,如果是,則執(zhí)行死鎖解除策略哥捕。
(4) 死鎖解除:這是與死鎖檢測(cè)結(jié)合使用的牧抽,它使用的方式就是剝奪。即將某進(jìn)程所擁有的資源強(qiáng)行收回遥赚,分配給其他的進(jìn)程阎姥。