分布式互斥锁,基于Redis的SET NX命令
实现了一个基于 Redis 的分布式锁机制,包含获取锁和释放锁的逻辑。
1. 获取锁的逻辑:
private boolean tryLock(String key) {
Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);
// 避免返回值为null,这里使用了BooleanUtil工具类
return BooleanUtil.isTrue(flag);
}
解析:
-
setIfAbsent方法:setIfAbsent是 Spring Data Redis 提供的方法,底层对应 Redis 的SET NX命令。该方法的作用是:- 如果键
key不存在,则将其设置为指定值(此处为"1"),并设置过期时间(此处为 10 秒)。 - 如果键已存在,则不执行任何操作。
- 如果键
- 该方法返回一个
Boolean对象:- 如果键不存在且设置成功,返回
true。 - 如果键已存在,返回
false。 - 在某些情况下,可能返回
null(例如,操作失败或出现异常)。
- 如果键不存在且设置成功,返回
-
使用
BooleanUtil.isTrue(flag):- 由于
setIfAbsent方法可能返回null,直接对其进行布尔判断可能导致NullPointerException。 BooleanUtil.isTrue(flag)是一个工具方法,等价于Boolean.TRUE.equals(flag),可以安全地判断flag是否为true,避免空指针异常。
- 由于
2. 释放锁的逻辑:
private void unlock(String key) {
stringRedisTemplate.delete(key);
}
解析:
delete方法:delete方法用于删除指定的键key,对应 Redis 的DEL命令。- 调用此方法会直接删除 Redis 中的键,无论其是否存在。
注意事项:
- 释放锁的安全性:
- 在分布式环境中,释放锁时需要确保只有持有锁的线程或进程才能删除该锁,避免误删其他线程或进程的锁。
- 一种常见的做法是在设置锁时,将一个唯一标识(如 UUID)作为值存入 Redis,释放锁时先获取 Redis 中的值,确认是自己设置的锁后再执行删除操作。
总结:
上述代码通过 setIfAbsent 方法尝试获取锁,并在获取成功后设置过期时间,以防止死锁。释放锁时,直接删除对应的键。

浙公网安备 33010602011771号