產(chǎn)生死鎖的代碼
//Deadlock.java
class A{
synchronized void methodA(B b){
b.last();
}
synchronized void last(){
System.out.println("Inside A.last()");
}
}
class B{
synchronized void methodB(A a){
a.last();
}
synchronized void last(){
System.out.println("Inside B.last()");
}
}
class Deadlock implements Runnable{
A a = new A();
B b = new B();
Deadlock(){
Thread t = new Thread(this);
int count=200000;
t.start();
while(count-- >0);
a.methodA(b);
}
public void run(){
b.methodB(a);
}
public static void main(String args[]){
new Deadlock();
}
}
之后用預(yù)處理文件Deadlock.bat運(yùn)行
#!/bin/bash
for((c=1;c<=300;c++))
do
echo "$c times"
java Deadlock
done
注:linux下運(yùn)行bat文件:
- chmod +x 文件名
先用上面的命令把批處理文件修改為可執(zhí)行文件。 - ./文件名
執(zhí)行該文件勃痴。
運(yùn)行結(jié)果
如果發(fā)現(xiàn)沒有死鎖遥赚,可以把每個(gè)鎖占有時(shí)間count延長篓冲,或者加大迭代次數(shù)c。
產(chǎn)生死鎖的必要條件
- 互斥:指進(jìn)程對所分配到的資源進(jìn)行排它性使用缨硝,即在一段時(shí)間內(nèi)某資源只由一個(gè)進(jìn)程占用。如果此時(shí)還有其它進(jìn)程請求資源,則請求者只能等待步氏,直至占有資源的進(jìn)程用畢釋放。
- 占有等待:指進(jìn)程已經(jīng)保持占有一個(gè)資源徒爹,但又提出了新的資源請求荚醒,而該資源已被其它進(jìn)程占有,此時(shí)請求進(jìn)程阻塞隆嗅,但又對自己已獲得的其它資源保持不放界阁,等待申請的資源。
- 不可搶占:指進(jìn)程已獲得的資源胖喳,在未使用完之前泡躯,不能被搶占,只能在使用完時(shí)由自己釋放丽焊。
- 循環(huán)等待:指在發(fā)生死鎖時(shí)较剃,必然存在鎖和資源的環(huán)鏈,即進(jìn)程A占有鎖A申請鎖B粹懒,進(jìn)程B占有鎖B申請鎖C....進(jìn)程N(yùn)占用鎖N申請鎖A重付,這樣所有進(jìn)程都不能立即得到資源,形成死鎖凫乖。
代碼分析
首先是synchronized 關(guān)鍵字确垫,使用這個(gè)關(guān)鍵字來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼帽芽。當(dāng)一個(gè)線程訪問object的一個(gè)synchronized同步代碼塊或同步方法時(shí)删掀,其他線程對object中所有其它synchronized同步代碼塊或同步方法的訪問將被阻塞。
這樣使得兩個(gè)類的last函數(shù)相當(dāng)于一個(gè)資源鎖导街,不能同時(shí)被并行訪問披泪。
在主函數(shù)中新建一個(gè)deadlock對象,這個(gè)對象的構(gòu)造函數(shù)中會(huì)建一個(gè)線程搬瑰,當(dāng)線程調(diào)用start()函數(shù)時(shí)款票,會(huì)運(yùn)行run()函數(shù)控硼,run函數(shù)中使得b占用a的鎖,然后釋放艾少。接著回到t.start()的下一步卡乾,在設(shè)置的count毫秒內(nèi)使得a占有b的鎖。
使用預(yù)處理文件循環(huán)跑這個(gè)代碼缚够,使得有可能出現(xiàn)下面的情況:
b.methodB(a)的同時(shí)a.methodA(b)幔妨,在這兩個(gè)函數(shù)內(nèi)部調(diào)用的是對方的last函數(shù),但是由于synchronized 關(guān)鍵字使得只能有一個(gè)線程訪問對象的一個(gè)synchronized函數(shù)谍椅,其他的被阻塞误堡,所以造成了:a調(diào)用自己的methodA函數(shù),使得自己的last函數(shù)被阻塞雏吭,b也一樣锁施,這樣a和b同時(shí)在等待對方的last函數(shù),導(dǎo)致死鎖思恐。