<ruby id="c4vej"><bdo id="c4vej"></bdo></ruby>
<dd id="c4vej"><track id="c4vej"><video id="c4vej"></video></track></dd>
  • <dd id="c4vej"><track id="c4vej"></track></dd>

        溫馨提示×

        Redisson可重入鎖解鎖邏輯是什么

        發布時間:2023-02-13 09:26:49 來源:億速云 閱讀:58 作者:iii 欄目:開發技術

        這篇文章主要介紹“Redisson可重入鎖解鎖邏輯是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Redisson可重入鎖解鎖邏輯是什么”文章能幫助大家解決問題。

        相比較Redisson可重入鎖的加鎖邏輯,釋放鎖的邏輯就相對簡單一些。釋放鎖分為主動釋放和自動釋放兩種方式。

        主動釋放

        我們查看org.redisson.RedissonLock#unlock()方法:

        public void unlock() {
                try {
                    get(unlockAsync(Thread.currentThread().getId()));
                } catch (RedisException e) {
                    if (e.getCause() instanceof IllegalMonitorStateException) {
                        throw (IllegalMonitorStateException) e.getCause();
                    } else {
                        throw e;
                    }
                }
        //        Future<Void> future = unlockAsync();
        //        future.awaitUninterruptibly();
        //        if (future.isSuccess()) {
        //            return;
        //        }
        //        if (future.cause() instanceof IllegalMonitorStateException) {
        //            throw (IllegalMonitorStateException)future.cause();
        //        }
        //        throw commandExecutor.convertException(future);
            }

        同樣采用異步的方式釋放鎖,unlockAsync():

        public RFuture<Void> unlockAsync(long threadId) {
            // 異步方式釋放鎖
            RFuture<Boolean> future = unlockInnerAsync(threadId);
            CompletionStage<Void> f = future.handle((opStatus, e) -> {
                // 取消看門狗定時任務
                cancelExpirationRenewal(threadId);
                if (e != null) {
                    throw new CompletionException(e);
                }
                if (opStatus == null) {
                    IllegalMonitorStateException cause = new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: "
                            + id + " thread-id: " + threadId);
                    throw new CompletionException(cause);
                }
                return null;
            });
            return new CompletableFutureWrapper<>(f);
        }

        可以看到,首先調用unlockInnerAsync()方法釋放鎖,在釋放鎖之后,執行cancelExpirationRenewal(threadId)取消看門狗自動續期的定時任務。

        釋放鎖核心邏輯:

        protected RFuture<Boolean> unlockInnerAsync(long threadId) {
            /**
             * Redisson解鎖:通過LUA腳本釋放鎖,保證多個命令之間的原子性
             */
            return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
                    "if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +
                            "return nil;" +
                            "end; " +
                            "local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +
                            "if (counter > 0) then " +
                            "redis.call('pexpire', KEYS[1], ARGV[2]); " +
                            "return 0; " +
                            "else " +
                            "redis.call('del', KEYS[1]); " +
                            "redis.call('publish', KEYS[2], ARGV[1]); " +
                            "return 1; " +
                            "end; " +
                            "return nil;",
                    Arrays.asList(getRawName(), getChannelName()), LockPubSub.UNLOCK_MESSAGE, internalLockLeaseTime, getLockName(threadId));
        }

        Redisson可重入鎖的釋放還是通過LUA腳本實現,保證多個命令之間的原子性。

        基本流程:

        1、通過hexists指令判斷鎖是不是自己的,如果不是自己的鎖,說明非法釋放鎖,返回nil,

        2、如果是自己的鎖,通過hincrby將鎖的重入次數減1;

        3、判斷減1后的數是否大于0,如果減1后的數大于0,說明還沒有完全釋放鎖,則重置鎖的過期時間,并返回0;

        4、如果減1后的數已經等于0,說明已經完全釋放鎖,則通過del指令釋放鎖,并通過publish發布一條消息,告訴其它訂閱了這把鎖的線程,我已經釋放鎖了,你們可以過來獲取了;釋放鎖成功,返回1

        5、其它情況,返回nil;

        主動釋放鎖這塊考慮的不僅僅是對 key 進行處理,因為可能存在重入鎖,所以會先對 redis key 對應的 hash value 進行遞減,相當于減去重入次數。

        自動釋放

        當服務宕機時,看門狗不再看門,那么最多 30s 之后鎖被自動釋放;當設置鎖的超時時間時,鎖到了過期時間,自動釋放。

        關于“Redisson可重入鎖解鎖邏輯是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

        免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

        主題地圖

        ,日韩AV电影院
        <ruby id="c4vej"><bdo id="c4vej"></bdo></ruby>
        <dd id="c4vej"><track id="c4vej"><video id="c4vej"></video></track></dd>
      1. <dd id="c4vej"><track id="c4vej"></track></dd>