溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么進(jìn)行Lock總結(jié)

發(fā)布時間:2021-10-20 16:11:02 來源:億速云 閱讀:118 作者:柒染 欄目:大數(shù)據(jù)

今天就跟大家聊聊有關(guān)怎么進(jìn)行Lock總結(jié),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

Lock在我們?nèi)粘Q邪l(fā)中經(jīng)常會使用到,比如ReenTrantLock,ReentrantReadWriteLock,StampedLock (JDK1.8新增),下面就詳細(xì)介紹一下它們的使用方法。

  • ReenTrantLock

    ReenTrantLock支持公平鎖和非公平鎖,也是獨占鎖,下面來說一下ReenTrantLock下的方法和使用。

    1. lock: 獲取阻塞鎖。

      // 默認(rèn)是費公平鎖,可自定,在參數(shù)中增加 true-公平 false-非公平
      ReenTrantLock lockObjcet = new ReenTrantLock();
      try {
        // 獲取鎖 ,如果獲取不到則阻塞線程
        lockObjcet.lock();
        // 同步代碼塊
      } catch (Exception e) {
      
      } finally {
        // 釋放鎖
        lockObjcet.unLock();
      }


    2. **tryLock:**獲取非阻塞鎖,如果無法獲取到鎖,返回false,獲取到了返回true。

      ReenTrantLock lock = new ReenTrantLock();
      if (lock.tryLock()) {
        // 獲取到了鎖
      } else {
        // 沒有獲取到鎖
      }


    3. **tryLock(time):**獲取非阻塞超時鎖,在time時間內(nèi)如果獲取到了鎖,返回true,獲取不到鎖返回false。

      ReenTrantLock lock = new ReenTrantLock();
      // 獲取鎖,如果在指定時間內(nèi)還未獲得,則返回false
      if (lock.tryLock(100)) {
        // 獲取到了鎖
      } else {
        // 沒有獲取到鎖
      }


    4. lockInterruptibly(): 獲取可中斷鎖,和lock區(qū)別就是在獲取鎖的過程中可以中斷線程。

    5. unlock(): 解鎖

    6. boolean isHeldByCurrentThread(): 判斷鎖是否是當(dāng)前線程持有,是返回true,不是返回false。

    7. boolean isLocked(): 判斷鎖是否被獲取或占用。

    8. boolean isFair(): 是否是公平鎖,是 返回true, 不是返回false。

    9. Thread getOwner(): 獲取當(dāng)前鎖的擁有者, 如果有擁有者則返回?fù)碛姓?,如果沒有返回null。

    10. boolean hasQueuedThreads(): 判斷是否有等待線程,如果有則返回true,反之false。

    11. boolean hasQueuedThread(Thread thread): 判斷入?yún)⒌木€程是否存在于等待隊列中,如果存在則返回true,反之false。

    12. int getQueueLength(): 獲取等待隊列中線程總數(shù)。

    13. Collection<Thread> getQueuedThreads(): 獲取等待隊列中的所有線程。

    14. boolean hasWaiters(Condition condition): 否有線程在與此鎖關(guān)聯(lián)的給定條件上等待,有返回true 反之 false。

    15. int getWaitQueueLength(Condition condition): 獲取被參數(shù) 條件等待的線程總數(shù)。

    16. Collection<Thread> getWaitingThreads(Condition condition): 獲取當(dāng)前鎖的條件等待的所有線程.

  • ReentrantReadWriteLock

    讀寫鎖: 讀鎖可以多線程一起獲取,寫鎖只有一個線程可以獲取,讀寫鎖支持公平鎖和非公平鎖,支持重入鎖。

    讀鎖: 可以被多個線程共同獲取鎖,同時進(jìn)入代碼塊。

    寫鎖: 只允許一個線程獲取,如果當(dāng)前線程獲取到寫鎖后,發(fā)現(xiàn)有線程獲取了讀鎖,并且不是當(dāng)前線程,這時當(dāng)前線程就進(jìn)入等待狀態(tài)。

    代碼示例:

    // 讀寫鎖
    private  ReadWriteLock rw = new ReentrantReadWriteLock();
    // 讀鎖 共享鎖
    private  Lock r = rw.readLock();
    // 寫鎖 排它鎖
    private  Lock w = rw.writeLock();

     

    • WriteLock

    • ReadLock

    1. lock(): 加鎖。

    2. unlock(): 解鎖。

    1. lock(): 寫鎖為獨占鎖,當(dāng)線程A獲取到了寫鎖時任何線程都不能獲取到讀鎖和寫鎖,如果線程A獲取到了寫鎖,但是讀鎖已經(jīng)被線程B獲取并且未釋放,這時就需要將線程A狀態(tài)改為等待,等待線程B釋放了寫鎖再繼續(xù)執(zhí)行。

    2. unlock(): 解鎖。

  • StampedLock (JDK1.8新增)

    StampedLock: 讀寫鎖,但是StampedLockReenTrantReadWriteLock更塊,但是StampedLock 用于 樂觀讀鎖,悲觀讀 鎖,和 寫鎖,StampedLock不支持重入鎖,StampedLock 的悲觀讀鎖、寫鎖都不支持條件變量。

    代碼示例:

    /**
     * @Auther: lantao
     * @Date: 2019-05-05 17:55
     * @Company: 隨行付支付有限公司
     * @maill: lan_tao@suixingpay.com
     * @Description: TODO
     */
    public class StampedLockTest {
    
        static StampedLock s =new StampedLock();
    
        public static void main(String[] args) {
    
            // 悲觀讀
            long l = s.readLock();
    
            // 釋放悲觀讀
            s.unlockRead(l);
    
    
            // 悲觀寫
            long l1 = s.writeLock();
    
            // 釋放悲觀寫
            s.unlockWrite(l1);
    
    
            // 樂觀讀 升級 悲觀讀
            long l2 = s.tryOptimisticRead();
    
            //驗證是否被修改 如果返回false 會釋放 l2,所以后續(xù)直接釋放l3即可
            if (!s.validate(l2)){
                // 升級悲觀讀
                long l3 = s.readLock();
                s.unlockRead(l3);
            }
        }
    }


    1. tryOptimisticRead: 樂觀讀。

    2. readLock: 悲觀讀。

    3. writeLock: 悲觀寫。

  • Conditionn

    Condition: Lock 的條件 ,其實初始化的是ConditionObject, ConditionObject是Condition的實現(xiàn),singal和signlAll的時候需要在獲取鎖后。**

    代碼示例:

    /**
     * @Auther: lantao
     * @Date: 2019-04-15 14:49
     * @Company: 隨行付支付有限公司
     * @maill: lan_tao@suixingpay.com
     * @Description: Condition 條件 有 singal signalAll 和 await 方法 和Object 的 notify notifyAll 和 wait 是一個意思同樣會釋放鎖  執(zhí)行singal和notify的時候也需要在等待獲取鎖
     */
    public class LockCondition {
    
        public static ReentrantLock lock = new ReentrantLock();
    
        public static Condition a = lock.newCondition();
    
        public static Condition b = lock.newCondition();
    
        public static void main(String[] args) throws InterruptedException {
            Runnable runnable = () -> {
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName());
                    a.await();
    
                    System.out.println(Thread.currentThread().getName() +  " 的 a conndition 被喚醒了");
    
                    b.await();
    
                    System.out.println(Thread.currentThread().getName() +  " 的 b conndition 被喚醒了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            };
    
            Runnable runnable1 = () -> {
                try {
                    lock.lock();
                    System.out.println("線程" +Thread.currentThread().getName() + " 開始執(zhí)行a condition sinalAll");
                    a.signalAll();
    
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            };
    
            Runnable runnable2 = () -> {
                try {
                    lock.lock();
                    System.out.println("線程" +Thread.currentThread().getName() + " 開始執(zhí)行b condition sinalAll");
                    b.signalAll();
    
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            };
    
            new Thread(runnable,"Thread1").start();
            new Thread(runnable,"Thread2").start();
            Thread.sleep(100);
            new Thread(runnable1,"Thread3").start();
            Thread.sleep(100);
            new Thread(runnable2,"Thread4").start();
        }
    }
    
    // 執(zhí)行結(jié)果
    Thread1
    Thread2
    線程Thread3 開始執(zhí)行a condition sinalAll
    Thread1 的 a conndition 被喚醒了
    Thread2 的 a conndition 被喚醒了
    線程Thread4 開始執(zhí)行b condition sinalAll
    Thread1 的 b conndition 被喚醒了
    Thread2 的 b conndition 被喚醒了

看完上述內(nèi)容,你們對怎么進(jìn)行Lock總結(jié)有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI