<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    和風細雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術自出。

    線程的死鎖

    本文內容

    同步不是改善程序安全性的靈丹妙藥。
    發生死鎖的兩種情況和解決方法。

    同步不是改善程序安全性的靈丹妙藥

    從《線程的同步》一節中我們可以知道,synchronized能保證只有一個線程進入同步方法或同步塊,但為了安全性盲目給多線程程序加上synchronized關鍵字并不是問題解決之道,這不但會降低程序的效率;還有可能帶來嚴重的問題-死鎖。
    死鎖發生在兩個或以上的線程在等待對象鎖被釋放,但程序的環境卻讓lock無法釋放時。下面我們將看到兩種類型的死鎖例子。

    某線程不退出同步函數造成的死鎖

    public class PaintBoard  extends Thread{
      private boolean flag=true;
     
      public void paint(){   
        System.out.println("模擬繪畫");
      }
     
      public synchronized void run(){
        while(flag){
          try{
            paint();
            Thread.sleep(1000);
          }
          catch(InterruptedException ex){
            ex.printStackTrace();
          }
        }
      }
     
      public synchronized void stopDraw(){
        flag=false;
        System.out.println("禁止繪畫");
      }
     
      public static void main(String[] args){
        PaintBoard paintBoard=new PaintBoard();
        paintBoard.start();
        new StopThread(paintBoard);
      }
    }

    public class StopThread implements Runnable{
      private PaintBoard paintBoard;
     
      public StopThread(PaintBoard paintBoard){
        this.paintBoard=paintBoard;
       
        Thread th=new Thread(this);
        th.start();
      }
     
      public void run(){
        while(true){
          System.out.println("試圖停止繪畫過程");
          paintBoard.stopDraw();
          System.out.println("停止繪畫過程完成");
        }
      }
    }

    問題的發生和解決

    剛才的死鎖原因是run()函數中有一個無限循環,一個線程進入后會在其中往復操作,這使它永遠不會放棄對this的鎖定,結果導致其它線程無法獲得this的鎖定而進入stopDraw函數。
    我們把修飾run函數的synchronized取消就能解決問題。 run函數中不會改變任何量,這種函數是不該加上synchronized的。

    兩個線程爭搶資源造成的死鎖.

    public class Desk{
      private Object fork=new Object();
      private Object knife=new Object();
     
      public void eatForLeft(){
        synchronized(fork){
          System.out.println("左撇子拿起叉");
          sleep(1);
          synchronized(knife){
            System.out.println("左撇子拿起刀");
            System.out.println("左撇子開始吃飯");
          }
        }
      }
     
      public void eatForRight(){
        synchronized(knife){
          System.out.println("右撇子拿起刀");
          sleep(1);
          synchronized(fork){
            System.out.println("右撇子拿起叉");
            System.out.println("右撇子開始吃飯");
          }
        }
      }
     
      private void sleep(int second){
        try{
          Thread.sleep(second*1000);
        }
        catch(InterruptedException ex){
          ex.printStackTrace();
        }
      }
     
      public static void main(String[] args){
        Desk desk=new Desk();
        new LeftHand(desk);
        new RightHand(desk);
      }
    }

    public class LeftHand implements Runnable{
      private Desk desk;
     
      public LeftHand(Desk desk){
        this.desk=desk;
       
        Thread th=new Thread(this);
        th.start();
      }
     
      public void run(){
        while(true){
          desk.eatForLeft();
        }
      }
    }

    public class RightHand implements Runnable{
      private Desk desk;
     
      public RightHand(Desk desk){
        this.desk=desk;
       
        Thread th=new Thread(this);
        th.start();
      }
     
      public void run(){
        while(true){
          desk.eatForRight();
        }
      }
    }

    問題的發生和解決

    這部分程序中于兩個線程都要獲得兩個對象的鎖定才能執行實質性操作,但運行起來卻發現其它線程持有了自己需要的另一個鎖定,于是停在Wait Set中等待對方釋放這個鎖定,結果造成了死鎖。
    解決這個問題的方法是保證鎖對象的持有順序,如果兩個加上了同步的函數都是先刀后叉的形式則不會發生問題。

    小結

    同步不是改善程序安全性的靈丹妙藥,盲目同步也會導致嚴重的問題-死鎖.
    某線程持續不退出同步函數會造成死鎖.解決方法是去掉或更換不正確的同步。
    兩個線程都等待對方釋放自己需要的資源也會造成死鎖.這種情況的解決方法是確保同步鎖對象的持有順序。

    posted on 2008-02-22 14:11 和風細雨 閱讀(786) 評論(0)  編輯  收藏 所屬分類: 線程

    主站蜘蛛池模板: 亚洲AV永久无码精品放毛片| 久久WWW免费人成—看片| 国产乱子影视频上线免费观看| 羞羞漫画小舞被黄漫免费| 国产偷国产偷亚洲清高动态图| 久久成人a毛片免费观看网站| 亚洲人成片在线观看| 亚洲?V无码成人精品区日韩 | 亚洲码和欧洲码一码二码三码| 亚洲А∨精品天堂在线| 国产成人免费视频| 亚洲成AV人片在WWW| 亚洲成A人片777777| 美女被免费视频网站a国产| 两性色午夜视频免费播放| 亚洲一区AV无码少妇电影| 国产亚洲一区二区精品| 日本二区免费一片黄2019| 一级毛片在线免费看| 精品久久久久亚洲| 亚洲福利视频网站| 中文字幕久久亚洲一区| 影音先锋在线免费观看| 欧洲人免费视频网站在线| 理论片在线观看免费| 亚洲免费视频播放| 亚洲精品国偷自产在线| 免费观看a级毛片| 美丽的姑娘免费观看在线播放| 国产久爱免费精品视频 | 亚洲男人电影天堂| 国产亚洲成人在线播放va| 性感美女视频免费网站午夜| 无码人妻AV免费一区二区三区| 成年免费a级毛片| 中文字幕精品三区无码亚洲| 亚洲日本国产精华液| 亚洲成av人在线视| 亚洲狠狠婷婷综合久久久久| 免费大片黄手机在线观看| 日韩视频免费一区二区三区|