1、多線程死鎖


          a. 死鎖分析:


             假設A和B同時在吃意大利面,而吃意大利面的條件是左手使用湯勺,右手使用叉子。現在只有一副餐具,A拿到了湯勺,B拿到了叉子,A等待B放下叉子,B等待A放下湯勺。則形成了死鎖。


          b. 出現死鎖的條件:

          • 具有多個SharedResource參與者,相當于湯勺和叉子。
          • 線程鎖定了一個SharedResource之后,在未解鎖的情況下去鎖定另一個SharedResource參與者,相當于A在擁有了湯勺之后,又去拿叉子;B在擁有了叉子之后又去拿湯勺。
          • 獲取SharedResource參與者的順序不固定,參與者順序對等,相當于湯勺和叉子的順序相同,沒有先后關系。


          c. 上述1、2、3三個條件只要破壞了其中一種,則就解決了死鎖的問題。


          2、提高多線程執行性能的兩種方式:


          減少 SharedResource參與者參與者的個數,從而減少synchronized使用數量,減少獲取對象鎖的操作時間

          盡量縮短臨界區范圍,從而減少線程沖突時等待的時間。


          3、自己設計線程鎖

          oid method() {
              lock(); //
              try {
                  ..
              } finally {
                  unlock(); //最后無論什么情況都要解鎖
              }
          }

          4、原子操作

          • 用synchronized定義的方法或者塊都具有原子性,只能被一個線程使用
          • long、double為非原子性,其他類型以及對象等引用都是具有原子性
          • 在定義long、double類型變量時,使用volatile修飾,表示對這個字段變量的定義為不可分隔的

          總結:

          • 基本類型、引用類型為原子操作
          • long、double為可以分割的
          • 在多線程中使用其作為共享參與者使用時,要么在使用時的方法用synchronized定義,或者使用volatile聲明
          5、意大利面死鎖問題解決方案

          設計思路是將湯勺和叉子作為一個整體去處理,這樣就解決了死鎖的問題。
          還有一種方法就是在添加湯勺和叉子時是有序的,必須先拿湯勺,再拿叉子,這樣也可以解決死鎖問題。


          //主方法,用于創建處理
          public class Main {
              public static void main(String[] args) {
                  Tool spoon = new Tool("spoon");
                  Tool fork = new Tool("fork");
                  Tools tools = new Tools(spoon, fork);
                  new EaterThread(tools, "shma").start();
                  new EaterThread(tools, "jjq").start();
              }

          }
           1 // 吃意大利面的線程 不斷的吃
           2 class EaterThread extends Thread {
           3     private String name;
           4     private final Tool leftHand;
           5     private final Tool rightHand;
           6     public EaterThread(Tools tools, String name) {
           7         super();
           8         this.leftHand = tools.getSpoon();
           9         this.name = name;
          10         this.rightHand = tools.getFork();
          11     }
          12     public void eat() {
          13         synchronized(leftHand) {
          14             System.out.println(name + " takes up " + leftHand + "(left)");
          15             synchronized(rightHand) {
          16                 System.out.println(name + " takes up " + rightHand + "(right)");
          17                 System.out.println(name + " is eating now!");
          18                 System.out.println(name + " puts down " + rightHand + "(right)");
          19             }
          20             System.out.println(name + " puts down " + leftHand + "(left)");
          21         }
          22     }
          23 
          24     @Override
          25     public void run() {
          26         while(true) {
          27             eat();
          28             try {
          29                 Thread.sleep(1000);
          30             } catch (InterruptedException e) {
          31                 // TODO Auto-generated catch block
          32                 e.printStackTrace();
          33             }
          34         }
          35     }
          36 
          37 }


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          posts - 0, comments - 0, trackbacks - 0, articles - 2

          Copyright © 馬少

          版權所有 侵權必究
          主站蜘蛛池模板: 和林格尔县| 类乌齐县| 岱山县| 沈阳市| 砚山县| 保山市| 沁水县| 兴山县| 中西区| 芷江| 济南市| 夏邑县| 青海省| 湘西| 搜索| 西乡县| 永宁县| 东城区| 白山市| 石屏县| 科技| 理塘县| 龙口市| 罗源县| 深水埗区| 黎平县| 鄄城县| 奈曼旗| 会理县| 延寿县| 渭源县| 茌平县| 许昌市| 麻栗坡县| 嘉祥县| 清远市| 五原县| 濉溪县| 仁寿县| 辛集市| 怀宁县|