<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試題:用java實(shí)現(xiàn)一個死鎖

          共 5719字,需瀏覽 12分鐘

           ·

          2021-05-30 08:52

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)


          實(shí)現(xiàn)一個最簡單的死鎖(Java版)

          /**
           * @author wall
           * @date 2019/7/29  16:42
           * @description 實(shí)現(xiàn)一個死鎖:A線程獲取B線程占有的鎖,B線程獲取A線程占有的鎖
           */
          public class DeadLock {
              //定義兩把鎖
              private static ReentrantLock lockA = new ReentrantLock();
              private static ReentrantLock lockB = new ReentrantLock();
              //測試
              public static void main(String[] args) {
                  //啟動線程A,B
                  new Thread(new A()).start();
                  new Thread(new B()).start();
              }
           
              static class A implements Runnable{
                  @Override
                  public void run() {
                      Thread.currentThread().setName("A線程");
                      //獲取鎖A
                      lockA.lock();
                      System.out.println(Thread.currentThread().getName()+"獲取鎖A");
                      //模擬業(yè)務(wù)操作
                      try {
                          Thread.sleep(5000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      //再獲取鎖B
                      lockB.lock();
                      System.out.println(Thread.currentThread().getName()+"獲取鎖B");
                      lockA.unlock();
                      lockB.unlock();
                  }
              }
           
              static class B implements Runnable{
                  @Override
                  public void run() {
                      Thread.currentThread().setName("B線程");
                      //獲取鎖B
                      lockB.lock();
                      System.out.println(Thread.currentThread().getName()+"獲取鎖B");
                      //模擬業(yè)務(wù)操作
                      try {
                          Thread.sleep(5000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      //再獲取鎖A
                      lockA.lock();
                      System.out.println(Thread.currentThread().getName()+"獲取鎖A");
                  }
              }
          }

          產(chǎn)生死鎖的四大必要條件

          ①資源互斥/資源不共享

          互斥條件:一個資源每次只能被一個進(jìn)程使用。

          ②占有和等待/請求并保持

          (請求與保持條件:一個進(jìn)程因請求資源而阻塞時(shí),對已獲得的資源保持不放。

          ③資源不可剝奪

           進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。

          ④環(huán)路等待

          若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。

          舉個例子▼

          小明有鍵盤,小白有鼠標(biāo),小明要用電腦打游戲,小白要用電腦做PPT,小明沒有鼠標(biāo)沒法打游戲,小白沒有鍵盤沒法做PPT,小明等小白把鼠標(biāo)給自己,小白也等小明把鍵盤給自己,但是小明不愿意把鍵盤給小白,小白也不愿意把鼠標(biāo)給小明,小明和小白也不能互相搶鍵盤和鼠標(biāo),他倆之間就形成了死鎖。

                                                                        

          避免死鎖的方式

          1. 銀行家算法

          2. 避免多次鎖定。盡量避免同一個線程對多個 Lock 進(jìn)行鎖定。例如上面的死鎖程序,主線程要對 A、B 兩個對象的 Lock 進(jìn)行鎖定,副線程也要對 A、B 兩個對象的 Lock 進(jìn)行鎖定,這就埋下了導(dǎo)致死鎖的隱患。

          3. 具有相同的加鎖順序。(給鎖添加順序)如果多個線程需要對多個 Lock 進(jìn)行鎖定,則應(yīng)該保證它們以相同的順序請求加鎖。比如上面的死鎖程序,主線程先對 A 對象的 Lock 加鎖,再對 B 對象的 Lock 加鎖;而副線程則先對 B 對象的 Lock 加鎖,再對 A 對象的 Lock 加鎖。這種加鎖順序很容易形成嵌套鎖定,進(jìn)而導(dǎo)致死鎖。如果讓主線程、副線程按照相同的順序加鎖,就可以避免這個問題。

          4. 使用定時(shí)鎖。程序在調(diào)用 acquire() 方法加鎖時(shí)可指定 timeout 參數(shù),該參數(shù)指定超過 timeout 秒后會自動釋放對 Lock 的鎖定,這樣就可以解開死鎖了。

          5. 死鎖檢測。死鎖檢測是一種依靠算法機(jī)制來實(shí)現(xiàn)的死鎖預(yù)防機(jī)制,它主要是針對那些不可能實(shí)現(xiàn)按序加鎖,也不能使用定時(shí)鎖的場景的。

          死鎖的解除

          1、資源剝奪法

          掛起某些死鎖進(jìn)程,并搶占它的資源,將這些資源分配給其他的死鎖進(jìn)程。但應(yīng)防止被掛起的進(jìn)程長時(shí)間得不到資源,而處于資源匱乏的狀態(tài)。

          2、撤銷進(jìn)程法

          強(qiáng)制撤銷部分、甚至全部死鎖進(jìn)程并剝奪這些進(jìn)程的資源。撤銷的原則可以按進(jìn)程優(yōu)先級和撤銷進(jìn)程代價(jià)的高低進(jìn)行。

          3、進(jìn)程回退法

          讓一(多)個進(jìn)程回退到足以回避死鎖的地步,進(jìn)程回退時(shí)自愿釋放資源而不是被剝奪。要求系統(tǒng)保持進(jìn)程的歷史信息,設(shè)置還原點(diǎn)。


          版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。

          本文鏈接:

          https://blog.csdn.net/weixin_42228338/article/details/97686461








          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  最好看2019中文在线播放电影 | 看黑人免费操逼 | 欧美日韩肏逼 | 激情内射免费视频 | 淫色777 |