面试

加锁流程:

  1. 客户端执行 SET lock_key uuid EX 30 NX
  2. Redis 检查 lock_key 是否存在
  3. 不存在则设置成功,返回 OK,加锁成功
  4. 已存在则返回 nil,加锁失败

解锁流程:

  1. 客户端执行 Lua 脚本
  2. GET lock_key 获取当前值
  3. 判断值是否等于自己的 uuid
  4. 相等则 DEL lock_key,解锁成功
  5. 不相等则返回 0,说明锁不是自己的

加锁命令

SET lock_key uuid EX 30 NX

解锁 Lua 脚本

if redis.call("GET", KEYS[1]) == ARGV[1]
then
    return redis.call("DEL", KEYS[1])
else
    return 0
end

Java 代码实现

public class RedisLock {
    private Jedis jedis;
    private String lockKey;
    private String uuid;
    private int expireTime = 30; // 秒

    public boolean tryLock() {
        uuid = UUID.randomUUID().toString();
        String result = jedis.set(lockKey, uuid, SetParams.setParams().nx().ex(expireTime));
        return "OK".equals(result);
    }

    public void unlock() {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                        "return redis.call('del', KEYS[1]) else return 0 end";
        jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(uuid));
    }
}
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐