<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>

          一文詳解讀寫鎖

          共 3780字,需瀏覽 8分鐘

           ·

          2022-05-13 01:06

          作者 | 磊哥

          來源 | Java面試真題解析(ID:aimianshi666)

          轉(zhuǎn)載請聯(lián)系授權(quán)(微信ID:GG_Stone)

          讀寫鎖(Readers-Writer Lock)顧名思義是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個線程同時獲得,因為讀操作本身是線程安全的,而寫鎖則是互斥鎖,不允許多個線程同時獲得寫鎖,并且寫操作和讀操作也是互斥的。總結(jié)來說,讀寫鎖的特點是:讀讀不互斥、讀寫互斥、寫寫互斥

          1.讀寫鎖使用

          在 Java 語言中,讀寫鎖是使用 ReentrantReadWriteLock 類來實現(xiàn)的,其中:

          • ReentrantReadWriteLock.ReadLock 表示讀鎖,它提供了 lock 方法進(jìn)行加鎖、unlock 方法進(jìn)行解鎖。
          • ReentrantReadWriteLock.WriteLock 表示寫鎖,它提供了 lock 方法進(jìn)行加鎖、unlock 方法進(jìn)行解鎖。

          它的基礎(chǔ)使用如下代碼所示:

          //?創(chuàng)建讀寫鎖
          final?ReentrantReadWriteLock?readWriteLock?=?new?ReentrantReadWriteLock();
          //?獲得讀鎖
          final?ReentrantReadWriteLock.ReadLock?readLock?=?readWriteLock.readLock();
          //?獲得寫鎖
          final?ReentrantReadWriteLock.WriteLock?writeLock?=?readWriteLock.writeLock();
          //?讀鎖使用
          readLock.lock();
          try?{
          ????//?業(yè)務(wù)代碼...
          }?finally?{
          ????readLock.unlock();
          }
          //?寫鎖使用
          writeLock.lock();
          try?{
          ????//?業(yè)務(wù)代碼...
          }?finally?{
          ????writeLock.unlock();
          }

          1.1 讀讀不互斥

          多個線程可以同時獲取到讀鎖,稱之為讀讀不互斥,如下代碼所示:

          //?創(chuàng)建讀寫鎖
          final?ReentrantReadWriteLock?readWriteLock?=?new?ReentrantReadWriteLock();
          //?創(chuàng)建讀鎖
          final?ReentrantReadWriteLock.ReadLock?readLock?=?readWriteLock.readLock();
          Thread?t1?=?new?Thread(()?->?{
          ????readLock.lock();
          ????try?{
          ????????System.out.println("[t1]得到讀鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t1]釋放讀鎖.");
          ????????readLock.unlock();
          ????}
          });
          t1.start();
          Thread?t2?=?new?Thread(()?->?{
          ????readLock.lock();
          ????try?{
          ????????System.out.println("[t2]得到讀鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t2]釋放讀鎖.");
          ????????readLock.unlock();
          ????}
          });
          t2.start();

          以上程序執(zhí)行結(jié)果如下:

          1.2 讀寫互斥

          讀鎖和寫鎖同時使用是互斥的(也就是不能同時獲得),這稱之為讀寫互斥,如下代碼所示:

          //?創(chuàng)建讀寫鎖
          final?ReentrantReadWriteLock?readWriteLock?=?new?ReentrantReadWriteLock();
          //?創(chuàng)建讀鎖
          final?ReentrantReadWriteLock.ReadLock?readLock?=?readWriteLock.readLock();
          //?創(chuàng)建寫鎖
          final?ReentrantReadWriteLock.WriteLock?writeLock?=?readWriteLock.writeLock();
          //?使用讀鎖
          Thread?t1?=?new?Thread(()?->?{
          ????readLock.lock();
          ????try?{
          ????????System.out.println("[t1]得到讀鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t1]釋放讀鎖.");
          ????????readLock.unlock();
          ????}
          });
          t1.start();
          //?使用寫鎖
          Thread?t2?=?new?Thread(()?->?{
          ????writeLock.lock();
          ????try?{
          ????????System.out.println("[t2]得到寫鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t2]釋放寫鎖.");
          ????????writeLock.unlock();
          ????}
          });
          t2.start();

          以上程序執(zhí)行結(jié)果如下:

          1.3 寫寫互斥

          多個線程同時使用寫鎖也是互斥的,這稱之為寫寫互斥,如下代碼所示:

          //?創(chuàng)建讀寫鎖
          final?ReentrantReadWriteLock?readWriteLock?=?new?ReentrantReadWriteLock();
          //?創(chuàng)建寫鎖
          final?ReentrantReadWriteLock.WriteLock?writeLock?=?readWriteLock.writeLock();
          Thread?t1?=?new?Thread(()?->?{
          ????writeLock.lock();
          ????try?{
          ????????System.out.println("[t1]得到寫鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t1]釋放寫鎖.");
          ????????writeLock.unlock();
          ????}
          });
          t1.start();

          Thread?t2?=?new?Thread(()?->?{
          ????writeLock.lock();
          ????try?{
          ????????System.out.println("[t2]得到寫鎖.");
          ????????Thread.sleep(3000);
          ????}?catch?(InterruptedException?e)?{
          ????????e.printStackTrace();
          ????}?finally?{
          ????????System.out.println("[t2]釋放寫鎖.");
          ????????writeLock.unlock();
          ????}
          });
          t2.start();

          以上程序執(zhí)行結(jié)果如下:

          2.優(yōu)點分析

          1. 提高了程序執(zhí)行性能:多個讀鎖可以同時執(zhí)行,相比于普通鎖在任何情況下都要排隊執(zhí)行來說,讀寫鎖提高了程序的執(zhí)行性能。

          2. 避免讀到臨時數(shù)據(jù):讀鎖和寫鎖是互斥排隊執(zhí)行的,這樣可以保證了讀取操作不會讀到寫了一半的臨時數(shù)據(jù)。

          3.適用場景

          讀寫鎖適合多讀少寫的業(yè)務(wù)場景,此時讀寫鎖的優(yōu)勢最大。

          總結(jié)

          讀寫鎖是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個線程同時獲得,而寫鎖則是互斥鎖。它的完整規(guī)則是:讀讀不互斥、讀寫互斥、寫寫互斥。它適用于多讀的業(yè)務(wù)場景,使用它可以有效的提高程序的執(zhí)行性能,也能避免讀取到操作了一半的臨時數(shù)據(jù)。

          是非審之于己,毀譽(yù)聽之于人,得失安之于數(shù)。

          公眾號:Java面試真題解析

          面試合集:https://gitee.com/mydb/interview


          往期推薦

          面試突擊44:volatile 有什么用?


          面試突擊43:lock、tryLock、lockInterruptibly有什么區(qū)別?


          面試突擊42:synchronized和ReentrantLock有什么區(qū)別?


          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  免费看操片| 国产三级a三级三级 | 日韩三级片网站 | 午夜久久乐 | 麻酥酥在线视频 |