redis+Lua实现分布式锁

1.方法lock(String lock, int expire) :获取锁

expire,锁的过期时间

setnx(),只有当lock不存在时才会赋值,赋值成功返回1,赋值失败返回0


 public boolean lock(String lock, int expire) throws Exception {

        Assert.notNull(lock, "lock must not be null");

        long expireTime = getExpireTime(expire);

        return RedisUtils.setnx(lock, expireTime) ==1;

    }


2.方法softUnlock(String lock):解锁,只有当锁过期时才会解锁

使用Lua脚本script,获取锁的状态以及解锁,这两步操作必须为原子性操作


public boolean softUnlock(String lock)throws Exception {

        Assert.notNull(lock, "lock must not be null");

        String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) < ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";

       String currentTime = String.valueOf(System.currentTimeMillis());

       String expireCode = String.valueOf(RedisUtils.eval(script, lock, currentTime));

       return RELEASE_SUCCESS.equals(expireCode)

}


3.方法hardUnlock(String lock):解锁,不关心锁的是否过期


    public boolean hardUnlock(String lock) throws Exception {

            Assert.notNull(lock, "lock must not be null");

            RedisUtils.del(lock);

            return true;

    }


4.方法getLockStatus(String lock):获取锁的状态


public boolean getLockStatus(String lock) throws Exception {

        String value = RedisUtils.get(lock);

        return value ==null || Long.parseLong(value) < System.currentTimeMillis();

    }


5.方法autoIncrLock(String lock):锁的值自加1,如果锁本身不存在,默认从0开始


public String autoIncrLock(String lock) throws Exception {

        Assert.notNull(lock, "lock must not be null");

        lock = assembleKey(AUTO, lock);

        String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('incr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";

        String value = String.valueOf(RedisUtils.eval(script, lock, "1"));

        logger.info("autoIncrLock success#lock={},value={}", lock, value);

        return value;

    }


6.方法autoDecrLock(String lock):锁的值自减1,如果锁本身不存在,默认从0开始


public String autoDecrLock(String lock) throws Exception {

        Assert.notNull(lock, "lock must not be null");

        lock = assembleKey(AUTO, lock);

        String script ="if redis.call('exists',KEYS[1]) == 1 then redis.call('decr', KEYS[1]) else redis.call('set',KEYS[1],ARGV[1]) end return redis.call('get', KEYS[1])";

        String value = String.valueOf(RedisUtils.eval(script, lock, "-1"));

        logger.info("autoDecrLock success#lock={},value={}", lock, value);

        return value;

    }


7.方法softUnlockAuto(String lock):解锁,只有当锁过期时才会解锁


public boolean softUnlockAuto(String lock) throws Exception {

        Assert.notNull(lock, "lock must not be null");

        lock = assembleKey(AUTO, lock);

        String script ="if redis.call('exists', KEYS[1]) == 1 then if redis.call('get', KEYS[1]) <= ARGV[1] then redis.call('del', KEYS[1]) return 1 else return 0 end else return 1 end";

        String code = String.valueOf(RedisUtils.eval(script, lock, "0"));         

        return RELEASE_SUCCESS.equals(code);

}


8.方法hardUnlockAuto(String lock):解锁,不关心当前锁的状态


public boolean hardUnlockAuto(String lock) throws Exception {

                lock = assembleKey(AUTO, lock);

                return hardUnlock(lock);

    }


9.方法String assembleKey(String... section):组装key


public String assembleKey(String... section) throw Exception {

        List sections =new ArrayList(Arrays.asList(section));

        Joiner joiner = Joiner.on(KEY_PRE_CON_SIGN).skipNulls();

        return joiner.join(sections);

    }


10.方法getExpireTime(int expire): 获取过期时间


private String getExpireTime(int expire) throws Exception {

        Assert.isTrue(expire > 0, "expire must be greater than 0");

        long expireTime = System.currentTimeMillis() + expire +1;

        return String.valueOf(expireTime);

    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容