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);

    }

你可能感兴趣的:(redis+Lua实现分布式锁)