轉(zhuǎn)帖|其它|編輯:郝浩|2010-05-11 11:43:14.000|閱讀 763 次
概述:Java線程死鎖需要如何解決,這個(gè)問(wèn)題一直在我們不斷的使用中需要只有不斷的關(guān)鍵。不幸的是,使用上鎖會(huì)帶來(lái)其他問(wèn)題。讓我們來(lái)看一些常見(jiàn)問(wèn)題以及相應(yīng)的解決方法。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
Java線程死鎖需要如何解決,這個(gè)問(wèn)題一直在我們不斷的使用中需要只有不斷的關(guān)鍵。不幸的是,使用上鎖會(huì)帶來(lái)其他問(wèn)題。讓我們來(lái)看一些常見(jiàn)問(wèn)題以及相應(yīng)的解決方法。
Java線程死鎖
Java線程死鎖是一個(gè)經(jīng)典的多線程問(wèn)題,因?yàn)椴煌木€程都在等待那些根本不可能被釋放的鎖,從而導(dǎo)致所有的工作都無(wú)法完成。假設(shè)有兩個(gè)線程,分別代表兩個(gè)饑餓的人,他們必須共享刀叉并輪流吃飯。他們都需要獲得兩個(gè)鎖:共享刀和共享叉的鎖。
假如線程 “A”獲得了刀,而線程“B”獲得了叉。線程“A”就會(huì)進(jìn)入阻塞狀態(tài)來(lái)等待獲得叉,而線程“B”則阻塞來(lái)等待“A”所擁有的刀。這只是人為設(shè)計(jì)的例子,但盡管在運(yùn)行時(shí)很難探測(cè)到,這類情況卻時(shí)常發(fā)生。雖然要探測(cè)或推敲各種情況是非常困難的,但只要按照下面幾條規(guī)則去設(shè)計(jì)系統(tǒng),就能夠避免Java線程死鎖問(wèn)題:
讓所有的線程按照同樣的順序獲得一組鎖。這種方法消除了 X 和 Y 的擁有者分別等待對(duì)方的資源的問(wèn)題。
將多個(gè)鎖組成一組并放到同一個(gè)鎖下。前面Java線程死鎖的例子中,可以創(chuàng)建一個(gè)銀器對(duì)象的鎖。于是在獲得刀或叉之前都必須獲得這個(gè)銀器的鎖。
將那些不會(huì)阻塞的可獲得資源用變量標(biāo)志出來(lái)。當(dāng)某個(gè)線程獲得銀器對(duì)象的鎖時(shí),就可以通過(guò)檢查變量來(lái)判斷是否整個(gè)銀器集合中的對(duì)象鎖都可獲得。如果是,它就可以獲得相關(guān)的鎖,否則,就要釋放掉銀器這個(gè)鎖并稍后再嘗試。
最重要的是,在編寫(xiě)代碼前認(rèn)真仔細(xì)地設(shè)計(jì)整個(gè)系統(tǒng)。多線程是困難的,在開(kāi)始編程之前詳細(xì)設(shè)計(jì)系統(tǒng)能夠幫助你避免難以發(fā)現(xiàn)Java線程死鎖的問(wèn)題。
Volatile 變量,volatile 關(guān)鍵字是 Java 語(yǔ)言為優(yōu)化編譯器設(shè)計(jì)的。以下面的代碼為例:
1.class VolatileTest { 2.public void foo() { 3.boolean flag = false; 4.if(flag) { 5.//this could happen 6.} 7.} 8.} |
一個(gè)優(yōu)化的編譯器可能會(huì)判斷出if部分的語(yǔ)句永遠(yuǎn)不會(huì)被執(zhí)行,就根本不會(huì)編譯這部分的代碼。如果這個(gè)類被多線程訪問(wèn), flag被前面某個(gè)線程設(shè)置之后,在它被if語(yǔ)句測(cè)試之前,可以被其他線程重新設(shè)置。用volatile關(guān)鍵字來(lái)聲明變量,就可以告訴編譯器在編譯的時(shí)候,不需要通過(guò)預(yù)測(cè)變量值來(lái)優(yōu)化這部分的代碼。
無(wú)法訪問(wèn)的Java線程死鎖有時(shí)候雖然獲取對(duì)象鎖沒(méi)有問(wèn)題,線程依然有可能進(jìn)入阻塞狀態(tài)。在 Java 編程中IO就是這類問(wèn)題最好的例子。當(dāng)線程因?yàn)閷?duì)象內(nèi)的IO調(diào)用而阻塞時(shí),此對(duì)象應(yīng)當(dāng)仍能被其他線程訪問(wèn)。該對(duì)象通常有責(zé)任取消這個(gè)阻塞的IO操作。造成阻塞調(diào)用的線程常常會(huì)令同步任務(wù)失敗。如果該對(duì)象的其他方法也是同步的,當(dāng)線程被阻塞時(shí),此對(duì)象也就相當(dāng)于被冷凍住了。
其他的線程由于不能獲得對(duì)象的Java線程死鎖,就不能給此對(duì)象發(fā)消息(例如,取消 IO 操作)。必須確保不在同步代碼中包含那些阻塞調(diào)用,或確認(rèn)在一個(gè)用同步阻塞代碼的對(duì)象中存在非同步方法。盡管這種方法需要花費(fèi)一些注意力來(lái)保證結(jié)果代碼安全運(yùn)行,但它允許在擁有對(duì)象的線程發(fā)生阻塞后,該對(duì)象仍能夠響應(yīng)其他線程。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載