大战熟女丰满人妻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學院官網。



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

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 日本乱中文字幕系列在线观看 | 国产成人精品亚洲777图片 | 九九久久九九 | 九九亚洲精品自拍 | 99久热只有精品视频免费看 | 精品中文字幕久久久久久 | 久色阁 | 亚洲一区二区三区久久 | 免费一级特黄欧美大片久久网 | 免费一级特黄欧美大片勹久久网 | 日本中文不卡 | 中文视频在线观看 | 性丰满妇女free性性性 | 日韩免费一级毛片 | 亚洲精品黄色 | 国产在线不卡视频 | 亚洲国产精品成人综合久久久 | 国产91在线免费 | 一级特黄特黄的大片免费 | 日本不卡视频在线播放 | 一级特黄性色生活片 | 成人a毛片在线看免费全部播放 | 国产精品亚洲第一区广西莫菁 | 免费播放欧美毛片 | 日韩一区二区三区在线 | 亚洲欧美日韩中文高清一 | 四虎永久影院永久影库 | 香蕉狠狠干 | 亚洲欧美日韩国产vr在线观 | 青青操网址 | 久亚洲精品不子伦一区 | 一级大片视频 | 亚洲第一永久色 | 香蕉超级碰碰碰97视频蜜芽 | 久久亚洲精品专区蓝色区 | 日日摸夜夜摸狠狠摸日日碰夜夜做 | 久久黄色精品视频 | 日韩欧国产精品一区综合无码 | 综合网天天操天天射 | 久久久99精品久久久 | 成人久久18免费网站游戏 |