<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无码一区二区三区牛牛| 久草免费手机视频| 亚洲av永久无码制服河南实里| 中国国产高清免费av片| 亚洲日韩欧洲乱码AV夜夜摸 | 亚洲剧场午夜在线观看| 99re在线精品视频免费| 亚洲的天堂av无码| 日本一区二区三区免费高清| 日韩亚洲国产高清免费视频| 日韩免费视频播放| 日亚毛片免费乱码不卡一区| 日韩精品亚洲aⅴ在线影院| 久草免费福利视频| 亚洲国产综合在线| 青草草在线视频永久免费| 国产在亚洲线视频观看| 国产午夜亚洲精品理论片不卡 | 亚洲中文字幕视频国产| 免费观看成人久久网免费观看| 亚洲精品福利视频| 青娱分类视频精品免费2| 香蕉视频亚洲一级| 亚洲成亚洲乱码一二三四区软件| 免费福利在线播放| 美女被艹免费视频| 亚洲av无码一区二区三区网站| 亚洲一区二区免费视频| 风间由美在线亚洲一区| 亚洲av永久无码精品网站| 免费观看美女用震蛋喷水的视频| 亚洲av永久无码天堂网| 国产AV无码专区亚洲AV漫画| xxxxwww免费| 一个人看的免费视频www在线高清动漫 | 久久久久久亚洲AV无码专区| 国产成人精品免费直播| a级日本高清免费看| 亚洲色成人网站WWW永久四虎|