大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java多線程之死鎖的出現和解決方法

Java多線程之死鎖的出現和解決方法

更新時間:2019-08-18 09:00:00 來源:動力節點 瀏覽2516次

 


    什么是死鎖?


  死鎖是這樣一種情形:多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放.由于線程被無限期地阻塞,因此程序不能正常運行.形象的說就是:一個寶藏需要兩把鑰匙來打開,同時間正好來了兩個人,他們一人一把鑰匙,但是雙方都再等著對方能交出鑰匙來打開寶藏,誰都沒釋放自己的那把鑰匙.就這樣這倆人一直僵持下去,直到開發人員發現這個局面。


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


  舉個例子


  死鎖的產生大部分都是在你不知情的時候.我們通過一個例子來看下什么是死鎖。


  1、synchronized嵌套

  synchronized關鍵字可以保證多線程再訪問到synchronized修飾的方法的時候保證了同步性.就是線程A訪問到這個方法的時候線程B同時也來訪問這個方法,這時線程B將進行阻塞,等待線程A執行完才可以去訪問.這里就要用到synchronized所持有的同步鎖.具體來看代碼:


/首先我們先定義兩個final的對象鎖.可以看做是共有的資源.

 final Object lockA = new Object();

 final Object lockB = new Object();

//生產者A

 class ProductThreadA implements Runnable{

   @Override

   public void run() {

//這里一定要讓線程睡一會兒來模擬處理數據 ,要不然的話死鎖的現象不會那么的明顯.這里就是同步語句塊里面,首先獲得對象鎖lockA,然后執行一些代碼,隨后我們需要對象鎖lockB去執行另外一些代碼.

     synchronized (lockA){

     //這里一個log日志

       Log.e("CHAO","ThreadA lock lockA");

       try {

         Thread.sleep(2000);

       } catch (InterruptedException e) {

         e.printStackTrace();

       }

       synchronized (lockB){

        //這里一個log日志

         Log.e("CHAO","ThreadA lock lockB");

         try {

           Thread.sleep(2000);

         } catch (InterruptedException e) {

           e.printStackTrace();

         }

 

       }

     }

   }

 }

 //生產者B

 class ProductThreadB implements Runnable{

 //我們生產的順序真好好生產者A相反,我們首先需要對象鎖lockB,然后需要對象鎖lockA.

   @Override

   public void run() {

     synchronized (lockB){

      //這里一個log日志

       Log.e("CHAO","ThreadB lock lockB");

       try {

         Thread.sleep(2000);

       } catch (InterruptedException e) {

         e.printStackTrace();

       }

       synchronized (lockA){

        //這里一個log日志

         Log.e("CHAO","ThreadB lock lockA");

         try {

           Thread.sleep(2000);

         } catch (InterruptedException e) {

           e.printStackTrace();

         }

 

       }

     }

   }

 }

 //這里運行線程

ProductThreadA productThreadA = new ProductThreadA();

ProductThreadB productThreadB = new ProductThreadB();

 

   Thread threadA = new Thread(productThreadA);

   Thread threadB = new Thread(productThreadB);

   threadA.start();

   threadB.start();


分析一下,當threadA開始執行run方法的時候,它會先持有對象鎖localA,然后睡眠2秒,這時候threadB也開始執行run方法,它持有的是localB對象鎖.當threadA運行到第二個同步方法的時候,發現localB的對象鎖不能使用(threadB未釋放localB鎖),threadA就停在這里等待localB鎖.隨后threadB也執行到第二個同步方法,去訪localA對象鎖的時候發現localA還沒有被釋放(threadA未釋放localA鎖),threadB也停在這里等待localA鎖釋放.就這樣兩個線程都沒辦法繼續執行下去,進入死鎖的狀態. 看下運行結果:


10-20 14:54:39.940 18162-18178/? E/CHAO: ThreadA lock lockA

10-20 14:54:39.940 18162-18179/? E/CHAO: ThreadB lock lockB


  當不會死鎖的時候應該是打印四條log的,這里明顯的出現了死鎖的現象。


  死鎖出現的原因


  當我們了解在什么情況下會產生死鎖,以及什么是死鎖的時候,我們在寫代碼的時候應該盡量的去避免這個誤區.產生死鎖必須同時滿足以下四個條件,只要其中任一條件不成立,死鎖就不會發生。


  互斥條件:線程要求對所分配的資源進行排他性控制,即在一段時間內某 資源僅為一個進程所占有.此時若有其他進程請求該資源.則請求進程只能等待。


  不剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能由獲得該資源的線程自己來釋放(只能是主動釋放)。


  請求和保持條件:線程已經保持了至少一個資源,但又提出了新的資源請求,而該資源已被其他線程占有,此時請求線程被阻塞,但對自己已獲得的資源保持不放。


  循環等待條件:存在一種線程資源的循環等待鏈,鏈中每一個線程已獲得的資源同時被鏈中下一個線程所請求。


  解決死鎖的方法


  1、解決死鎖主要方法如下:


  (1)不考慮此問題,樂觀的角度,鴕鳥算法


  (2)不讓死鎖發生:


  ①死鎖預防。


  靜態策略,通過設計合適的資源分配算法,不讓死鎖發生


  ②死鎖避免


  動態策略,以不讓死鎖發生為目標,跟蹤并評估資源分配過程,根據評估結果決策是否分配


  (3)讓死鎖發生:死鎖的檢測與解除


  2.死鎖預防的具體方法:主要是破壞產生死鎖的四個必要條件中的任何一個條件。


  (1)破壞“互斥使用/資源獨占”條件


  使用資源轉換技術,將獨占資源變為共享資源


  (2)破壞“占有且等待”條件


  ①方案1:每個進程在運行前必須一次性的申請它所要求的全部資源,且僅當該進程所要的資源均可滿足時才一次性的分配。


  資源利用率低,“饑餓”現象


  ②在允許進程動態申請資源的前提下規定,一個進行在申請新資源,且不能立即得到滿足,必須釋放已占有的全部資源。若需要再重新申請


  (3)破壞“不可搶占”條件


  可以通過操作系統搶占這一資源(根據進程的不同優先級)


  局限性:適用于狀態易于保存和恢復的資源,如CPU(搶占式的調度算法),內存(頁面置換算法)


  (4)破壞“循環等待”條件


  通過定義資源類型的線性順序實現


  方案:資源有序分配法。(如哲學家就餐問題)


  也就是把資源中所有的資源編號,進程在申請資源時,必須嚴格按照資源編號的遞增次序進行,否則操作系統不予分配。(資源使用的頻繁性?)


  3、死鎖避免的方法


1.png

  

  (1)對不同分區進行不同的處理,左下可同時分配資源;右下區域可能會產生死鎖,應該先分配P,釋放后再分配Q;左上同理;右上區域時會產生死鎖現象,不予分配資源。對可能發生死鎖和可能產生死鎖的不予分配資源,否則(安全狀態)分配資源。


  (2)安全狀態是指每個進程Pi以后還需要的資源量不超過系統當前剩余資源量與所有進程Pj當前占有資源量之和。


  4、死鎖的檢測與解除

  (1)允許死鎖發生,但是操作系統會不斷監視系統進展情況,判斷死鎖是否真的發生。(進程等待時檢測,定時檢測,系統資源利用率下降)


  (2)一旦死鎖發生,采用專門的措施,解除死鎖并以最小的代價恢復系統運行。


  以上就是動力節點java學院小編介紹的“Java多線程之死鎖的出現和解決方法”的相關內容,希望對大家有幫助,更多精彩內容請關注動力節點java學院官網。



提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 国产精品一区二区在线播放 | 亚洲成a人片77777kkk | 久久香蕉综合色一综合色88 | 国产日韩亚洲欧洲一区二区三区 | 久久综合伊人77777 | 国内精品久久久久久麻豆 | 久久九九有精品国产56 | 亚洲一区欧美二区 | 国产精品一级片 | 亚洲国产成人精彩精品 | 香香影院在线观看 | 日本黄色录像 | 亚洲伊人色一综合网 | 精品久久中文字幕有码 | 高清一区高清二区视频 | 成人一级视频 | 国产四区 | 波多野结衣乳巨码无在线观看 | 亚洲国产成人久久一区www妖精 | 99国产精品热久久久久久 | 免费观看性欧美毛片 | 亚洲成a人片在线观看精品 亚洲成a人一区二区三区 | 亚洲综合在线播放 | 欧美日韩精品 | 黄色网址视频在线播放 | 香蕉成人在线 | 中文字幕在线不卡视频 | 亚洲精品一区二区三区五区 | 成人深夜影院 | 精品亚洲综合在线第一区 | 日本又黄又爽又色的视频免费 | 色综综| 在线看v| 国产精品99r8在线观看 | 看全色黄大色大片免费久久久 | 99精品国产兔费观看66 | 午夜成人在线视频 | 91嫩草国产线免费观看 | 午夜视频入口 | 日韩欧美在线观看视频 | 色综合天天 |