簡單講就是不會再鎖上等待而是在隊列里等待。java object每一個對象都持有一個條件隊列,與當前內置鎖配合使用。

retrycount 帶有重試次數限制

等待遠程redis lock肯定是需要一定重試機制,但是這種重試是需要一定的限制。

    /**
     * 重試獲取鎖的次數,可以根據當前任務的執行時間來設置。
     * 需要時間=RetryCount*(WaitLockTimeSecond/1000)
     */
    private static final int RetryCount = 10;

這種等待是需要用戶指定的, if (isWait && retryCounts < RetryCount) ,當isWait為true才會進行重試。

object wait time 帶有超時時間的wait

object.wait(timeout),條件隊列中的方法wait是需要一個waittime。

    /**
     * 等待獲取鎖的時間,可以根據當前任務的執行時間來設置。
     * 設置的太短,浪費CPU,設置的太長鎖就不太公平。
     */
    private static final long WaitLockTimeSecond = 2000;

默認2000毫秒。

this.wait(WaitLockTimeSecond); //未能獲取到lock,進行指定時間的wait再重試.

注意:this.wait雖然會blocking住,但是這里的內置鎖是會立即釋放出來的。所以,有時候我們可以借助這種特性來優化特殊場景。

delete lock 刪除遠程鎖

釋放redis lock比較簡單,直接del key就好了

long status = jedis.del(lockKey);        if (status > 0) {
            logger.info(String.                    format(t:%s,當前節點:%s,釋放鎖:%s 成功。, Thread.currentThread().getId(), getRedisIdentityKey(), lockKey));            return true;
        }

一旦delete 之后,首先wait喚醒的線程將會獲得鎖。

acquire lock 申請lock

/**
     * 帶超時時間的redis lock.
     *
     * @param lockKeyExpireSecond 鎖key在redis中的過去時間
     * @param lockKey             lock key
     * @param isWait              當獲取不到鎖時是否需要等待
     * @throws Exception lockKey is empty throw exception.
     */
    public Boolean acquireLockWithTimeout(int lockKeyExpireSecond, String lockKey, Boolean isWait) throws Exception {        if (StringUtils.isEmpty(lockKey)) throw new Exception(lockKey is empty.);

        int retryCounts = 0;        while (true) {
            Long status, expire = 0L;
            status = jedis.setnx(lockKey, redisIdentityKey);/**設置 lock key.*/
            if (status > 0) {
                expire = jedis.expire(lockKey, lockKeyExpireSecond);/**set  redis key expire time.*/
            }            if (status > 0 && expire > 0) {
                logger.info(String.
                        format(t:%s,當前節點:%s,獲取到鎖:%s, Thread.currentThread().getId(), getRedisIdentityKey(), lockKey));                return true;/**獲取到lock*/
            }            try {                if (isWait && retryCounts < RetryCount) {
                    retryCounts  ;
                    synchronized (this) {//借助object condition queue 來提高CPU利用率
                        logger.info(String.
                                format(t:%s,當前節點:%s,嘗試等待獲取鎖:%s, Thread.currentThread().getId(), getRedisIdentityKey(), lockKey));                        this.wait(WaitLockTimeSecond); //未能獲取到lock,進行指定時間的wait再重試.
                    }
                } else if (retryCounts == RetryCount) {
                    logger.info(String.
                            format(t:%s,當前節點:%s,指定時間內獲取鎖失敗:%s, Thread.currentThread().getId(), getRedisIdentityKey(), lockKey));                    return false;
                } else {                    return false;//不需要等待,直接退出。
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
## release lock 釋放lock/**
     * 釋放redis lock。
     *
     * @param lockKey lock key
     * @throws Exception lockKey is empty throw exception.
     */
    public Boolean releaseLockWithTimeout(String lockKey) throws Exception {        if (StringUtils.isEmpty(lockKey)) throw new Exception(lockKey is empty.);

        long status = jedis.del(lockKey);        if (status > 0) {
            logger.info(String.format(當前節點:%s,釋放鎖:%s 成功。, getRedisIdentityKey(), lockKey));            return true;
        }
        logger.info(String.format(當前節點:%s,釋放鎖:%s 失敗。, getRedisIdentityKey(), lockKey));        return false;
    }

demo 演示

2017-06-18 13:57:43.867 INFO 1444 — [nio-8080-exec-1] c.plen.opensource.implement.RedisLocker : t:23,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,獲取到鎖:product:10100101:shopping
2017-06-18 13:57:47.062 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:49.063 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:51.064 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:53.066 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:55.068 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:57.069 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:57:59.070 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:01.071 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:03.072 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:05.073 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:07.074 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,指定時間內獲取鎖失敗:product:10100101:shopping
2017-06-18 13:58:23.768 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:25.769 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:27.770 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:29.772 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:31.773 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:33.774 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:35.774 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,獲取到鎖:product:10100101:shopping

thread 23 優先獲取到對商品ID 10100101 進行修改,所以先鎖住當前商品。

t:23,當前節點:843d3ec0-9c22-4d8a-bcaa-745dba35b8a4,獲取到鎖:product:10100101:shopping

緊接著,thread 25也來對當前商品 10100101進行修改,所以在嘗試獲取鎖。

2017-06-18 13:50:11.021 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:13.023 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:15.026 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:17.028 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:19.030 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:21.031 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:23.035 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:25.037 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:27.041 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:29.042 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:50:35.289 INFO 4616 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:946b7250-29f3-459b-8320-62d31e6f1fc4,指定時間內獲取鎖失敗:product:10100101:shopping

在進行了retry10次(2000毫秒,2秒)之后,獲取失敗,直接返回,等待下次任務調度開始。

2017-06-18 13:58:07.074 INFO 1444 — [nio-8080-exec-3] c.plen.opensource.implement.RedisLocker : t:25,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,指定時間內獲取鎖失敗:product:10100101:shopping
2017-06-18 13:58:23.768 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:25.769 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:27.770 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:29.772 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:31.773 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:33.774 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,嘗試等待獲取鎖:product:10100101:shopping
2017-06-18 13:58:35.774 INFO 1444 — [nio-8080-exec-6] c.plen.opensource.implement.RedisLocker : t:28,當前節點:5f81f482-295a-4394-b8cb-d7282e51dd6e,獲取到鎖:product:10100101:shopping

thread 28 發起對商品 10100101 進行修改,retry6次之后獲取到lock。

更多關于云服務器域名注冊,虛擬主機的問題,請訪問三五互聯官網:m.shinetop.cn

贊(0)
聲明:本網站發布的內容(圖片、視頻和文字)以原創、轉載和分享網絡內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。郵箱:3140448839@qq.com。本站原創內容未經允許不得轉載,或轉載時需注明出處:三五互聯知識庫 » redisLock redis分布式鎖

登錄

找回密碼

注冊

主站蜘蛛池模板: 亚洲综合久久精品国产高清| 亚洲国产精品自在拍在线播放蜜臀 | 国产伦精品一区二区三区| 亚洲av一本二本三本| 國產尤物AV尤物在線觀看| 亚洲熟妇自偷自拍另类| 亚洲中文字幕无码专区| 国产精品嫩草99av在线| 亚洲精品日本一区二区| 亚洲精品岛国片在线观看| 高清国产av一区二区三区| 盈江县| 欧美亚洲综合久久偷偷人人| 国产三级精品福利久久| 国产亚洲精品久久久久5区| 毛多水多高潮高清视频| 久草热大美女黄色片免费看| 国产精品久久国产三级国不卡顿| 亚洲一区二区精品极品| 国产办公室秘书无码精品99| 国精品午夜福利视频不卡| 鲁甸县| 中文字幕人妻有码久视频| 日韩有码中文在线观看| 国产一级小视频| 久热这里只有精品视频3| 内地偷拍一区二区三区| 亚洲日韩乱码一区二区三区四区| 精品人妻一区二区| 大香伊蕉在人线国产最新2005| 色播久久人人爽人人爽人人片av| 亚洲精品国产男人的天堂| 亚洲中文久久久精品无码| 国产成人无码www免费视频播放| 日韩av日韩av在线| 偷拍专区一区二区三区| 国产欧美精品一区二区三区四区 | 亚洲色成人一区二区三区 | 亚洲伊人久久综合成人| 亚洲精品国产男人的天堂| 久久人人爽人人爽人人片av|