死鎖
站在用戶的角度思考問題,與客戶深入溝通,找到大興安嶺網(wǎng)站設(shè)計(jì)與大興安嶺網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋大興安嶺地區(qū)。
死鎖是這樣一種情形:多個(gè)線程同時(shí)被阻塞,它們中的一個(gè)或者全部都在等待某個(gè)資源被釋放。由于線程被無限期地阻塞,因此程序不可能正常終止。
導(dǎo)致死鎖的根源在于不適當(dāng)?shù)剡\(yùn)用“synchronized”關(guān)鍵詞來管理線程對(duì)特定對(duì)象的訪問?!皊ynchronized”關(guān)鍵詞的作用是,確保在某個(gè)時(shí)刻只有一個(gè)線程被允許執(zhí)行特定的代碼塊,因此,被允許執(zhí)行的線程首先必須擁有對(duì)變量或?qū)ο蟮呐潘缘脑L問權(quán)。當(dāng)線程訪問對(duì)象時(shí),線程會(huì)給對(duì)象加鎖,而這個(gè)鎖導(dǎo)致其它也想訪問同一對(duì)象的線程被阻塞,直至第一個(gè)線程釋放它加在對(duì)象上的鎖。
由于這個(gè)原因,在使用“synchronized”關(guān)鍵詞時(shí),很容易出現(xiàn)兩個(gè)線程互相等待對(duì)方做出某個(gè)動(dòng)作的情形。代碼一是一個(gè)導(dǎo)致死鎖的簡單例子。
//代碼一
class Deadlocker {
int field_1;
private Object lock_1 = new int[1];
int field_2;
private Object lock_2 = new int[1];
public void method1(int value) {
“synchronized” (lock_1) {
“synchronized” (lock_2) {
field_1 = 0; field_2 = 0;
}
}
}
public void method2(int value) {
“synchronized” (lock_2) {
“synchronized” (lock_1) {
field_1 = 0; field_2 = 0;
}
}
}
}
參考代碼一,考慮下面的過程:
◆ 一個(gè)線程(ThreadA)調(diào)用method1()。
◆ ThreadA在lock_1上同步,但允許被搶先執(zhí)行。
◆ 另一個(gè)線程(ThreadB)開始執(zhí)行。
◆ ThreadB調(diào)用method2()。
◆ ThreadB獲得lock_2,繼續(xù)執(zhí)行,企圖獲得lock_1。但ThreadB不能獲得lock_1,因?yàn)門hreadA占有l(wèi)ock_1。
◆ 現(xiàn)在,ThreadB阻塞,因?yàn)樗诘却齌hreadA釋放lock_1。
◆ 現(xiàn)在輪到ThreadA繼續(xù)執(zhí)行。ThreadA試圖獲得lock_2,但不能成功,因?yàn)閘ock_2已經(jīng)被ThreadB占有了。
◆ ThreadA和ThreadB都被阻塞,程序死鎖。
當(dāng)然,大多數(shù)的死鎖不會(huì)這么顯而易見,需要仔細(xì)分析代碼才能看出,對(duì)于規(guī)模較大的多線程程序來說尤其如此。好的線程分析工具,例如JProbe Threadalyzer能夠分析死鎖并指出產(chǎn)生問題的代碼位置。
隱性死鎖
隱性死鎖由于不規(guī)范的編程方式引起,但不一定每次測(cè)試運(yùn)行時(shí)都會(huì)出現(xiàn)程序死鎖的情形。由于這個(gè)原因,一些隱性死鎖可能要到應(yīng)用正式發(fā)布之后才會(huì)被發(fā)現(xiàn),因此它的危害性比普通死鎖更大。下面介紹兩種導(dǎo)致隱性死鎖的情況:加鎖次序和占有并等待。
加鎖次序
當(dāng)多個(gè)并發(fā)的線程分別試圖同時(shí)占有兩個(gè)鎖時(shí),會(huì)出現(xiàn)加鎖次序沖突的情形。如果一個(gè)線程占有了另一個(gè)線程必需的鎖,就有可能出現(xiàn)死鎖??紤]下面的情形,ThreadA和ThreadB兩個(gè)線程分別需要同時(shí)擁有l(wèi)ock_1、lock_2兩個(gè)鎖,加鎖過程可能如下:
◆ ThreadA獲得lock_1;
◆ ThreadA被搶占,VM調(diào)度程序轉(zhuǎn)到ThreadB;
◆ ThreadB獲得lock_2;
◆ ThreadB被搶占,VM調(diào)度程序轉(zhuǎn)到ThreadA;
◆ ThreadA試圖獲得lock_2,但lock_2被ThreadB占有,所以ThreadA阻塞;
◆ 調(diào)度程序轉(zhuǎn)到ThreadB;
◆ ThreadB試圖獲得lock_1,但lock_1被ThreadA占有,所以ThreadB阻塞;
◆ ThreadA和ThreadB死鎖。
必須指出的是,在代碼絲毫不做變動(dòng)的情況下,有些時(shí)候上述死鎖過程不會(huì)出現(xiàn),VM調(diào)度程序可能讓其中一個(gè)線程同時(shí)獲得lock_1和lock_2兩個(gè)鎖,即線程獲取兩個(gè)鎖的過程沒有被中斷。在這種情形下,常規(guī)的死鎖檢測(cè)很難確定錯(cuò)誤所在。
占有并等待
如果一個(gè)線程獲得了一個(gè)鎖之后還要等待來自另一個(gè)線程的通知,可能出現(xiàn)另一種隱性死鎖,考慮代碼二。
//代碼二
public class queue {
static java.lang.Object queueLock_;
Producer producer_;
Consumer consumer_;
public class Producer {
void produce() {
while (!done) {
“synchronized” (queueLock_) {
produceItemAndAddItToQueue();
“synchronized” (consumer_) {
consumer_.notify();
}
}
}
}
public class Consumer {
consume() {
while (!done) {
“synchronized” (queueLock_) {
“synchronized” (consumer_) {
consumer_.wait();
}
removeItemFromQueueAndProcessIt();
}
}
}
}
}
}
在代碼二中,Producer向隊(duì)列加入一項(xiàng)新的內(nèi)容后通知Consumer,以便它處理新的內(nèi)容。問題在于,Consumer可能保持加在隊(duì)列上的鎖,阻止Producer訪問隊(duì)列,甚至在Consumer等待Producer的通知時(shí)也會(huì)繼續(xù)保持鎖。這樣,由于Producer不能向隊(duì)列添加新的內(nèi)容,而Consumer卻在等待Producer加入新內(nèi)容的通知,結(jié)果就導(dǎo)致了死鎖。
在等待時(shí)占有的鎖是一種隱性的死鎖,這是因?yàn)槭虑榭赡馨凑毡容^理想的情況發(fā)展—Producer線程不需要被Consumer占據(jù)的鎖。盡管如此,除非有絕對(duì)可靠的理由肯定Producer線程永遠(yuǎn)不需要該鎖,否則這種編程方式仍是不安全的。有時(shí)“占有并等待”還可能引發(fā)一連串的線程等待,例如,線程A占有線程B需要的鎖并等待,而線程B又占有線程C需要的鎖并等待等。
要改正代碼二的錯(cuò)誤,只需修改Consumer類,把wait()移出“synchronized”()即可。
line = bufferedReader.readLine();//死鎖位置
會(huì)等待,所以會(huì)。
用另一個(gè)線程讀、主線程檢測(cè)是否命令終止了。
主線程保持著A對(duì)象的鎖意思就是主線程正在處理A對(duì)象,其他線程不能處理,要等待主線程結(jié)束之后其他線程才能處理A對(duì)象。
同理副線程正在處理B對(duì)象,A不能處理,所以主線程結(jié)束不了,一直在等待。
兩個(gè)線程都運(yùn)行不下去了就叫做死鎖,程序崩潰。
加鎖的意思就是某線程正在處理某對(duì)象,其他線程不能處理。
手打不容易,明白不明白都給分吧- -、
你這個(gè)不是死鎖,就是flag的判斷有問題,每個(gè)線程都是自己把自己鎖住了,當(dāng)flag為true時(shí),看以下兩段代碼:
public synchronized void set(String name) {
if (flag)
try {
wait();
public synchronized void out() {
if (flag)
try {
wait();
兩個(gè)線程都在wait,當(dāng)然卡住不動(dòng)了。
看你的代碼,把set那段改成這樣應(yīng)該就好了:
public synchronized void set(String name) {
if (!flag)
try {
wait();
分享題目:java造成死鎖的代碼 java實(shí)現(xiàn)死鎖代碼
文章網(wǎng)址:http://jinyejixie.com/article26/dosjdcg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司、、網(wǎng)站制作、移動(dòng)網(wǎng)站建設(shè)、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)