有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`
基于 Redis 实现一个最简易的分布式锁
分布式锁是一种在不同机器上的不同进程之间同步操作的工具。在分布式系统中,因为资源不再受单一实例控制,传统的加锁方法(如 synchronized 或者 Lock)就不再适用。Redis 由于其天然的高性能和键过期特性,成为实现分布式锁的一个很好的选择。
以下是实现最简易的分布式锁的基本步骤:
1. 创建锁
要创建一个分布式锁,你需要确保锁在 Redis 中是唯一的。这通常通过使用 SETNX 命令来实现,SETNX 是“SET if Not eXists”的缩写。
public boolean lock(String lockKey, String uniqueValue, int lockExpireTime) {
Jedis jedis = new Jedis("localhost"); // Assuming Redis server is on localhost
String result = jedis.set(lockKey, uniqueValue, "NX", "EX", lockExpireTime);
// 判断是否成功获取到了锁
if ("OK".equals(result)) {
return true;
}
return false;
}
这段代码尝试在 Redis 中设置一个锁,key 是 lockKey,value 是 uniqueValue,而且只有在 lockKey 不存在时才会成功设置(NX 选项)。EX 表示我们设置了这个锁的过期时间(lockExpireTime),避免死锁的情况。
uniqueValue 通常是一个随机生成的 UUID,这样只有锁的持有者才能释放它。
2. 释放锁
当操作完成时,我们需要释放锁,以允许其他系统的进程获取它。
public boolean unlock(String lockKey, String uniqueValue) {
Jedis jedis = new Jedis("localhost"); // Assuming Redis server is on localhost
// 使用 Lua 脚本来保证原子性
String script =
"if redis.call('get', KEYS[1]) == ARGV[1] then" +
" return redis.call('del', KEYS[1])" +
"else" +
" return 0" +
"end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(uniqueValue));
// 判断是否成功释放了锁
return "1".equals(result.toString());
}
这段代码首先检查锁是否是由当前进程持有(即检查 lockKey 对应的 value 是否等于 uniqueValue),如果是,则删除这个 key 释放锁。
使用 Lua 脚本可以保证检查和删除操作的原子性。
注意事项
- 确保锁的安全性:使用唯一值配合 Lua 脚本确保安全地设置和释放锁。
- 避免死锁:通过为锁设定一个过期时间来预防死锁的发生。
- 锁的续期:在某些情况下,我们可能需要续期锁以避免在操作未完成情况下锁自动释放。
以上就是如何使用 Redis 实现一个最基本的分布式锁的步骤。


