1、多線程死鎖


          a. 死鎖分析:


             假設A和B同時在吃意大利面,而吃意大利面的條件是左手使用湯勺,右手使用叉子?,F在只有一副餐具,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 © 馬少

          版權所有 侵權必究
          主站蜘蛛池模板: 中西区| 伊金霍洛旗| 井冈山市| 景洪市| 新营市| 自贡市| 东乌珠穆沁旗| 弥勒县| 霍林郭勒市| 蓬溪县| 定结县| 正安县| 蒲江县| 乌兰浩特市| 屏东市| 华宁县| 搜索| 吉林市| 定远县| 乌兰浩特市| 襄城县| 万载县| 宜阳县| 淮滨县| 饶河县| 获嘉县| 邢台县| 陆川县| 江北区| 丰顺县| 昌邑市| 乐安县| 开平市| 太和县| 长顺县| 开化县| 五常市| 廊坊市| 全椒县| 兰考县| 唐山市|