新聞中心
Java線程死鎖需要如何解決,這個(gè)問(wèn)題一直在我們不斷的使用中需要只有不斷的關(guān)鍵。不幸的是,使用上鎖會(huì)帶來(lái)其他問(wèn)題。讓我們來(lái)看一些常見(jiàn)問(wèn)題以及相應(yīng)的解決方法:

創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),廣平企業(yè)網(wǎng)站建設(shè),廣平品牌網(wǎng)站建設(shè),網(wǎng)站定制,廣平網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,廣平網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
Java線程死鎖
Java線程死鎖是一個(gè)經(jīng)典的多線程問(wèn)題,因?yàn)椴煌木€程都在等待那些根本不可能被釋放的鎖,從而導(dǎo)致所有的工作都無(wú)法完成。假設(shè)有兩個(gè)線程,分別代表兩個(gè)饑餓的人,他們必須共享刀叉并輪流吃飯。他們都需要獲得兩個(gè)鎖:共享刀和共享叉的鎖。#t#
假如線程 “A”獲得了刀,而線程“B”獲得了叉。線程“A”就會(huì)進(jìn)入阻塞狀態(tài)來(lái)等待獲得叉,而線程“B”則阻塞來(lái)等待“A”所擁有的刀。這只是人為設(shè)計(jì)的例子,但盡管在運(yùn)行時(shí)很難探測(cè)到,這類(lèi)情況卻時(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è)鎖并稍后再?lài)L試。
最重要的是,在編寫(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ì)的。以下面的代碼為例:
- class VolatileTest {
- public void foo() {
- boolean flag = false;
- if(flag) {
- //this could happen
- }
- }
- }
一個(gè)優(yōu)化的編譯器可能會(huì)判斷出if部分的語(yǔ)句永遠(yuǎn)不會(huì)被執(zhí)行,就根本不會(huì)編譯這部分的代碼。如果這個(gè)類(lèi)被多線程訪問(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就是這類(lèi)問(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)其他線程。
網(wǎng)站欄目:Java線程死鎖如何避免這一悲劇
分享URL:http://www.5511xx.com/article/dpehdsg.html


咨詢(xún)
建站咨詢(xún)
