分佈式鎖的實現(java)

  當對接第三方接口時,每每會碰到同一時間發送了大量相同的請求,這個時候或許就是第三方發送接口的失誤了。而咱們須要作的就是針對這個狀況來強化咱們的系統。這個時候就須要用到分佈式鎖。讓這些請求只有一個能發送進來。redis

分佈式鎖的實現通常有三種:數據庫

  1. 基於數據庫的樂觀鎖;
  2. 基於redis的分佈式鎖;
  3. 基於zookeeper的分佈式鎖。

  這裏咱們講的是第二種:基於redis的分佈式鎖的原理以及實現。緩存

下面是代碼的實現:分佈式

public class DistributeLock {
    /**
     * setnx(key,value):若是key-value存在,緩存成功並返回1,不然返回0.
     * getset(key,value):返回舊的value,而後更新舊的value爲新的value.
     * expire(key,seconds):設置key的過時時間爲seconds秒.
     * get(key):獲取key對應的value,不存在返回nil.
     */

    private final static long expire = 1000; // 設置鎖的過時時間

    public static boolean getLockByRedis(Jedis jedis,String lock){
        boolean success = false;
        long flag = jedis.setnx(lock, String.valueOf(System.currentTimeMillis() + expire + 1));
        // 獲取分佈式鎖成功
        if (flag == 1) {
            success = true;
        }else{ // 可能其餘線程持有鎖,也有多是鎖超時
            long getVale = Long.valueOf(jedis.get(lock));
            if (getVale < System.currentTimeMillis()) { //超時
                String oldValue = jedis.getSet(lock,String.valueOf(System.currentTimeMillis() + expire + 1));
                if (oldValue != null) {
                    // 被其餘線程搶佔
                    if (Long.valueOf(oldValue) == getVale) {
                        success = false;
                    }else{
                        success = true;
                    }
                }

            }else{
                success = false;
            }
        }
        return success;
    }

    /**
     * 誰上鎖,誰釋放
     * @param jedis
     * @param lock
     */
    public static void releaseLock(Jedis jedis,String lock) {
        if (System.currentTimeMillis() <  Long.valueOf(jedis.get(lock))) {
            jedis.del(lock);
        }
    }
}
相關文章
相關標籤/搜索