java死鎖的偽代碼 死鎖 java

java 死鎖

死鎖

創(chuàng)新互聯(lián)公司從2013年成立,先為寧蒗等服務(wù)建站,寧蒗等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為寧蒗企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

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

導(dǎo)致死鎖的根源在于不適當?shù)剡\用“synchronized”關(guān)鍵詞來管理線程對特定對象的訪問?!皊ynchronized”關(guān)鍵詞的作用是,確保在某個時刻只有一個線程被允許執(zhí)行特定的代碼塊,因此,被允許執(zhí)行的線程首先必須擁有對變量或?qū)ο蟮呐潘缘脑L問權(quán)。當線程訪問對象時,線程會給對象加鎖,而這個鎖導(dǎo)致其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。

由于這個原因,在使用“synchronized”關(guān)鍵詞時,很容易出現(xiàn)兩個線程互相等待對方做出某個動作的情形。代碼一是一個導(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;

}

}

}

}

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

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

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

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

◆ ThreadB調(diào)用method2()。

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

◆ 現(xiàn)在,ThreadB阻塞,因為它在等待ThreadA釋放lock_1。

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

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

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

隱性死鎖

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

加鎖次序

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

◆ 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死鎖。

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

占有并等待

如果一個線程獲得了一個鎖之后還要等待來自另一個線程的通知,可能出現(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向隊列加入一項新的內(nèi)容后通知Consumer,以便它處理新的內(nèi)容。問題在于,Consumer可能保持加在隊列上的鎖,阻止Producer訪問隊列,甚至在Consumer等待Producer的通知時也會繼續(xù)保持鎖。這樣,由于Producer不能向隊列添加新的內(nèi)容,而Consumer卻在等待Producer加入新內(nèi)容的通知,結(jié)果就導(dǎo)致了死鎖。

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

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

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

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

會等待,所以會。

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

java的死鎖問題

樓上的,如果是死循環(huán),會一直輸出,不會停止,明顯是死鎖。

樓主:你這個是死鎖,主要就是出在循環(huán)的問題,你把super.notify();放在循環(huán)里就可以了。

一點一點講,A線程進入synchronized代碼塊中,首先喚醒一個正在等待的線程,當前肯定是沒有了,因為鎖的原因,然后A線程進入循環(huán),輸出"線程A:10",進入等待。

此時執(zhí)行的權(quán)限交給B線程,B線程進入synchronized代碼塊,執(zhí)行super.notify();喚醒了A線程,但是由于同步機制,現(xiàn)在A處于就緒狀態(tài),然后B線程進入循環(huán),輸出“線程B:9”,進入等待,此前A線程已經(jīng)喚醒了,執(zhí)行權(quán)交給A線程,繼續(xù)執(zhí)行,又循環(huán)一次,輸出“線程A:8”,然后進入等待,此時B現(xiàn)在也處于等待的狀態(tài)。然后就死鎖了。

樓主夠通俗不?

java怎么編程寫一個能導(dǎo)致死鎖的程序

額,這么簡單,就直接定義一個類,該類隨便定義實例化個Object對象,然后在類中再定義2個內(nèi)部線程類,線程一,對object使用synchronized,在synchronized塊中用個while(true)的死循環(huán)就好了,線程二,對object也是使用synchronized同步,至于synchronized塊中干啥,你自己看著辦,反正線程一死循環(huán)不會釋放object對象鎖,線程二是執(zhí)行不到里面的代碼塊的

JAVA死鎖

主線程保持著A對象的鎖意思就是主線程正在處理A對象,其他線程不能處理,要等待主線程結(jié)束之后其他線程才能處理A對象。

同理副線程正在處理B對象,A不能處理,所以主線程結(jié)束不了,一直在等待。

兩個線程都運行不下去了就叫做死鎖,程序崩潰。

加鎖的意思就是某線程正在處理某對象,其他線程不能處理。

手打不容易,明白不明白都給分吧- -、

java代碼轉(zhuǎn)成偽代碼

1. 請把下面的java代碼用偽代碼寫出來

偽代碼(Pseudocode)是一種算法描述語言。

使用偽代碼的目的是為了使被描述的算法可以容易地以任何一種編程語言(Pascal,C,Java,etc)實現(xiàn)。因此,偽代碼必須結(jié)構(gòu)清晰、代碼簡單、可讀性好,并且類似自然語言。

介于自然語言與編程語言之間。以編程語言的書寫形式指明算法職能。

使用偽代碼, 不用拘泥于具體實現(xiàn)。相比程序語言(例如Java, C++,C, Dephi 等等)它更類似自然語言。

它是半角式化、不標準的語言。可以將整個算法運行過程的結(jié)構(gòu)用接近自然語言的形式(可以使用任何一種你熟悉的文字,關(guān)鍵是把程序的意思表達出來)描述出來。

String path = "***"File f = new File(path);public void test (F f)File []fs = f遍歷文件夾;for(。){ if(fs[i]是文件){ 輸入 }else{ 遞歸test(fs[i]); }}。

2. JAVA 偽代碼

提示輸入一個大于2且11的數(shù)字

輸入一整型數(shù)值給Vertices,

if(Vertices 3 || Vertices 11){

提示重新輸入且應(yīng)輸入

退出程序

}else{

生成一個Vertices * Vertices 大小的數(shù)組Graph,

填充數(shù)組 :行號與列號相同填充0,其余填充10以內(nèi)隨機數(shù)

交換元素:以[i][j]位置的數(shù)值與[j][i]位置的數(shù)值互換

最后打印數(shù)組各元素

}

3. 請把下列用java代碼 用偽代碼寫出來

偽代碼(Pseudocode)是一種算法描述語言。使用偽代碼的目的是為了使被描述的算法可以容易地以任何一種編程語言(Pascal,C,Java,etc)實現(xiàn)。因此,偽代碼必須結(jié)構(gòu)清晰、代碼簡單、可讀性好,并且類似自然語言。 介于自然語言與編程語言之間。以編程語言的書寫形式指明算法職能。使用偽代碼, 不用拘泥于具體實現(xiàn)。相比程序語言(例如Java, C++,C, Dephi 等等)它更類似自然語言。它是半角式化、不標準的語言。可以將整個算法運行過程的結(jié)構(gòu)用接近自然語言的形式(可以使用任何一種你熟悉的文字,關(guān)鍵是把程序的意思表達出來)描述出來。

String path = "***"

File f = new File(path);

public void test (F f)

File []fs = f遍歷文件夾;

for(。){

if(fs[i]是文件){

輸入

}else{

遞歸test(fs[i]);

}

}

4. 偽代碼怎么寫

偽代碼(Pseudocode)是一種算法描述語言。

使用偽代碼的目的是為了使被描述的算法可以容易地以任何一種編程語言(Pascal,C,Java,etc)實現(xiàn)。因此,偽代碼必須結(jié)構(gòu)清晰、代碼簡單、可讀性好,并且類似自然語言。

介于自然語言與編程語言之間。 它以編程語言的書寫形式指明算法的職能。

相比于程序語言(例如Java, C++,C, Dephi 等等)它更類似自然語言。它是半角式化、不標準的語言。

我們可以將整個算法運行過程的結(jié)構(gòu)用接近自然語言的形式(這里,你可以使用任何一種你熟悉的文字,中文,英文 等等,關(guān)鍵是你把你程序的意思表達出來)描述出來. 使用偽代碼, 可以幫助我們更好的表述算法, 不用拘泥于具體的實現(xiàn). 人們在用不同的編程語言實現(xiàn)同一個算法時意識到,他們的實現(xiàn)(注意:這里是實現(xiàn),不是功能)很不同。尤其是對于那些熟練于不同編程語言的程序員要理解一個(用其他編程語言編寫的程序的)功能時可能很難,因為程序語言的形式限制了程序員對程序關(guān)鍵部分的理解。

這樣偽代碼就應(yīng)運而生了。 當考慮算法功能(而不是其語言實現(xiàn))時,偽代碼常常得到應(yīng)用。

計算機科學(xué)在教學(xué)中通常使用虛擬碼,以使得所有的程序員都能理解。 綜上,簡單的說,讓人便于理解的代碼。

不依賴于語言的,用來表示程序執(zhí)行過程,而不一定能編譯運行的代碼。在數(shù)據(jù)結(jié)構(gòu)講算法的時候用的很多。

5. 偽代碼的寫法

類Pascal語言的偽代碼的語法規(guī)則是: 在偽代碼中,每一條指令占一行(else if,例外)。指令后不跟任何符號(Pascal和C中語句要以分號結(jié)尾)。

偽代碼實例如下:

IF 九點以前 THEN

do 私人事務(wù);

ELSE 9點到18點 THEN

工作;

ELSE

下班;

END IF

這樣不但可以達到文檔的效果,同時可以節(jié)約時間。更重要的是,使結(jié)構(gòu)比較清晰,表達方式更加直觀。

偽代碼(Pseudocode)是一種算法描述語言。使用偽代碼的目的是為了使被描述的算法可以容易地以任何一種編程語言(Pascal,C,Java,etc)實現(xiàn)。因此,偽代碼必須結(jié)構(gòu)清晰、代碼簡單、可讀性好,并且類似自然語言。 介于自然語言與編程語言之間。

它以編程語言的書寫形式指明算法的職能。相比于程序語言(例如Java, C++,C, Dephi 等等)它更類似自然語言。它是半角式化、不標準的語言。

我們可以將整個算法運行過程的結(jié)構(gòu)用接近自然語言的形式(這里,你可以使用任何一種你熟悉的文字,中文,英文 等等,關(guān)鍵是你把你程序的意思表達出來)描述出來。使用偽代碼, 可以幫助我們更好的表述算法,不用拘泥于具體的實現(xiàn)。

6. 偽代碼的寫法

最低0.27元開通文庫會員,查看完整內(nèi)容 原發(fā)布者:wangwenjxnu 偽代碼偽代碼是用介于自然語言和計算機語言之間的文字和符號來描述算法。

每一行(或幾行)表示一個基本操作。它不用圖形符號,因此書寫方便、格式緊湊,也比較好懂,便于向程序過渡。

偽代碼的7個主要部分:(1)算法名稱(2)指令序列(3)輸入/輸出(4)分支選擇(5)賦值(6)循環(huán)(7)算法結(jié)束1.算法名稱兩種表示算法的偽代碼:過程(Procedure)函數(shù)(Function)過程和函數(shù)的區(qū)別是:過程是執(zhí)行一系列的操作,不需要返回操作的結(jié)果,無返回數(shù)據(jù);函數(shù)是執(zhí)行一系列的操作后,要將操作的結(jié)果返回,有返回數(shù)據(jù)。算法偽代碼的書寫規(guī)則:Procedure([])Function([])如:ProcedureHanoi_Tower()FunctionFac(x)表示名為Fac的一個函數(shù)。

FunctionProg(n)表示名為Prog的一個函數(shù)。2.指令序列指令序列是算法的主體。

指令序列的書寫規(guī)則:用Begin作為開始、用End作為結(jié)束;用“{”作為開始、用“/}”作為結(jié)束。例如:Begin指令序列;End或者:{指令序列;/}3.輸出/輸出輸入:Input輸出:Output或Return4.分支選擇兩種分支:IfThen{指令序列/}IfThen{。

新聞名稱:java死鎖的偽代碼 死鎖 java
標題URL:http://muchs.cn/article44/docoohe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站服務(wù)器托管、App開發(fā)、虛擬主機、網(wǎng)站導(dǎo)航手機網(wǎng)站建設(shè)

廣告

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

成都seo排名網(wǎng)站優(yōu)化