造成死鎖的java代碼 造成死鎖的java代碼是什么

java 死鎖

死鎖

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網綜合服務,包含不限于成都網站設計、成都做網站、望奎網絡推廣、小程序開發(fā)、望奎網絡營銷、望奎企業(yè)策劃、望奎品牌公關、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學生創(chuàng)業(yè)者提供望奎建站搭建服務,24小時服務熱線:18982081108,官方網址:bm7419.com

死鎖是這樣一種情形:多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由于線程被無限期地阻塞,因此程序不可能正常終止。

導致死鎖的根源在于不適當地運用“synchronized”關鍵詞來管理線程對特定對象的訪問?!皊ynchronized”關鍵詞的作用是,確保在某個時刻只有一個線程被允許執(zhí)行特定的代碼塊,因此,被允許執(zhí)行的線程首先必須擁有對變量或對象的排他性的訪問權。當線程訪問對象時,線程會給對象加鎖,而這個鎖導致其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。

由于這個原因,在使用“synchronized”關鍵詞時,很容易出現兩個線程互相等待對方做出某個動作的情形。代碼一是一個導致死鎖的簡單例子。

//代碼一

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;

}

}

}

}

參考代碼一,考慮下面的過程:

◆ 一個線程(ThreadA)調用method1()。

◆ ThreadA在lock_1上同步,但允許被搶先執(zhí)行。

◆ 另一個線程(ThreadB)開始執(zhí)行。

◆ ThreadB調用method2()。

◆ ThreadB獲得lock_2,繼續(xù)執(zhí)行,企圖獲得lock_1。但ThreadB不能獲得lock_1,因為ThreadA占有l(wèi)ock_1。

◆ 現在,ThreadB阻塞,因為它在等待ThreadA釋放lock_1。

◆ 現在輪到ThreadA繼續(xù)執(zhí)行。ThreadA試圖獲得lock_2,但不能成功,因為lock_2已經被ThreadB占有了。

◆ ThreadA和ThreadB都被阻塞,程序死鎖。

當然,大多數的死鎖不會這么顯而易見,需要仔細分析代碼才能看出,對于規(guī)模較大的多線程程序來說尤其如此。好的線程分析工具,例如JProbe Threadalyzer能夠分析死鎖并指出產生問題的代碼位置。

隱性死鎖

隱性死鎖由于不規(guī)范的編程方式引起,但不一定每次測試運行時都會出現程序死鎖的情形。由于這個原因,一些隱性死鎖可能要到應用正式發(fā)布之后才會被發(fā)現,因此它的危害性比普通死鎖更大。下面介紹兩種導致隱性死鎖的情況:加鎖次序和占有并等待。

加鎖次序

當多個并發(fā)的線程分別試圖同時占有兩個鎖時,會出現加鎖次序沖突的情形。如果一個線程占有了另一個線程必需的鎖,就有可能出現死鎖??紤]下面的情形,ThreadA和ThreadB兩個線程分別需要同時擁有l(wèi)ock_1、lock_2兩個鎖,加鎖過程可能如下:

◆ ThreadA獲得lock_1;

◆ ThreadA被搶占,VM調度程序轉到ThreadB;

◆ ThreadB獲得lock_2;

◆ ThreadB被搶占,VM調度程序轉到ThreadA;

◆ ThreadA試圖獲得lock_2,但lock_2被ThreadB占有,所以ThreadA阻塞;

◆ 調度程序轉到ThreadB;

◆ ThreadB試圖獲得lock_1,但lock_1被ThreadA占有,所以ThreadB阻塞;

◆ ThreadA和ThreadB死鎖。

必須指出的是,在代碼絲毫不做變動的情況下,有些時候上述死鎖過程不會出現,VM調度程序可能讓其中一個線程同時獲得lock_1和lock_2兩個鎖,即線程獲取兩個鎖的過程沒有被中斷。在這種情形下,常規(guī)的死鎖檢測很難確定錯誤所在。

占有并等待

如果一個線程獲得了一個鎖之后還要等待來自另一個線程的通知,可能出現另一種隱性死鎖,考慮代碼二。

//代碼二

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向隊列加入一項新的內容后通知Consumer,以便它處理新的內容。問題在于,Consumer可能保持加在隊列上的鎖,阻止Producer訪問隊列,甚至在Consumer等待Producer的通知時也會繼續(xù)保持鎖。這樣,由于Producer不能向隊列添加新的內容,而Consumer卻在等待Producer加入新內容的通知,結果就導致了死鎖。

在等待時占有的鎖是一種隱性的死鎖,這是因為事情可能按照比較理想的情況發(fā)展—Producer線程不需要被Consumer占據的鎖。盡管如此,除非有絕對可靠的理由肯定Producer線程永遠不需要該鎖,否則這種編程方式仍是不安全的。有時“占有并等待”還可能引發(fā)一連串的線程等待,例如,線程A占有線程B需要的鎖并等待,而線程B又占有線程C需要的鎖并等待等。

要改正代碼二的錯誤,只需修改Consumer類,把wait()移出“synchronized”()即可。

java執(zhí)行cmd命令時出現死鎖

line = bufferedReader.readLine();//死鎖位置

會等待,所以會。

用另一個線程讀、主線程檢測是否命令終止了。

java產生死鎖原因,代碼如下。

你這個不是死鎖,就是flag的判斷有問題,每個線程都是自己把自己鎖住了,當flag為true時,看以下兩段代碼:

public synchronized void set(String name) {

if (flag)

try {

wait();

public synchronized void out() {

if (flag)

try {

wait();

兩個線程都在wait,當然卡住不動了。

看你的代碼,把set那段改成這樣應該就好了:

public synchronized void set(String name) {

if (!flag)

try {

wait();

分享標題:造成死鎖的java代碼 造成死鎖的java代碼是什么
文章地址:http://bm7419.com/article18/dohgsdp.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、做網站網站建設、小程序開發(fā)、服務器托管、網站設計公司

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網站建設