<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 和風細雨 閱讀(794) 評論(0)  編輯  收藏 所屬分類: 線程

    主站蜘蛛池模板: 日韩亚洲精品福利| 5555在线播放免费播放| 精品久久久久久久免费人妻| 亚洲系列国产精品制服丝袜第| 美女视频黄a视频全免费网站色窝 美女被cao网站免费看在线看 | 在线观看国产情趣免费视频| 亚洲国产精品成人AV在线| 成年大片免费视频| 亚洲人av高清无码| 在线观看免费国产视频| 羞羞视频在线免费观看| 亚洲人成人网站在线观看| 国产福利在线观看永久免费| 亚洲精品乱码久久久久久 | 黄页网址在线免费观看| 亚洲国产天堂久久综合| 怡红院免费全部视频在线视频| 亚洲日韩精品无码专区网址| 午夜网站在线观看免费完整高清观看 | 色婷婷六月亚洲综合香蕉| 亚洲AⅤ视频一区二区三区| eeuss影院免费直达入口| 亚洲动漫精品无码av天堂| 9277手机在线视频观看免费| 在线亚洲午夜片AV大片| 免费A级毛片无码A| 国产偷伦视频免费观看| 亚洲人成伊人成综合网久久| yy6080亚洲一级理论| 免费人成黄页在线观看日本| 亚洲国产成人久久77| mm1313亚洲精品国产| 久久久久国产免费| 亚洲精品乱码久久久久久蜜桃图片| 亚洲 综合 国产 欧洲 丝袜| a级午夜毛片免费一区二区| 亚洲a级片在线观看| 国产精品亚洲美女久久久| 最近高清中文字幕免费| 青草久久精品亚洲综合专区| 亚洲AV日韩精品久久久久久|