🌟如果喜欢作者的讲解方式,关注作者不迷路,同时也可以看看我的其他文章! 感谢!!!
🌟 告别并发Bug!Redis分布式锁的正确打开方式
一、Redisson 是什么?
你可以把 Redisson 想象成一个 Redis 的“瑞士军刀”。 🛠️ 它是一个 Java 的 Redis 客户端,但不仅仅是客户端那么简单。它提供了很多基于 Redis 的分布式 Java 对象和服务,比如:
- 分布式锁 (Distributed Lock):就像一把锁,保证同一时间只有一个线程能访问某个资源。🔒
- 分布式集合 (Distributed Collections):比如 List、Set、Map 等,可以在多个 Java 应用之间共享数据。 📚
- 分布式队列 (Distributed Queue):让多个应用可以安全地进行消息传递。 📨
- 分布式计数器 (Distributed AtomicLong):可以安全地进行原子计数。 🔢
- 发布/订阅 (Pub/Sub):实现消息的发布和订阅。 📢
- 延迟队列 (Delayed Queue):可以延迟一段时间后执行任务。 ⏰
- 布隆过滤器 (Bloom Filter):高效地判断某个元素是否存在于一个集合中。 🌸
简单来说,Redisson 就是把 Redis 的能力封装成一个个易于使用的 Java 对象,让你可以更方便地构建分布式应用。
使用 Redisson 的好处?
- 简化分布式开发:不用自己写复杂的 Redis 命令和逻辑,直接使用 Redisson 提供的 Java 对象,就像操作本地对象一样。 🍰
- 高性能:Redisson 基于 Redis 的高性能特性,所以你的分布式应用也能获得高性能。 🚀
- 易于使用:Redisson 的 API 设计得很友好,学习曲线比较平缓。 📈
- 功能丰富:提供了各种常用的分布式对象和服务,满足各种场景的需求。 🎁
- 支持多种 Redis 部署模式:单机、主从、哨兵、集群等都支持。 🏘️
- 支持 Spring Boot:可以很方便地集成到 Spring Boot 项目中。 🌷
Redisson 快速入门
-
添加依赖
首先,在你的 Maven 或 Gradle 项目中添加 Redisson 的依赖。
- Maven:
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.25.0</version> </dependency>
- Gradle:
implementation 'org.redisson:redisson:3.25.0'
-
配置 Redisson
创建一个 Redisson 的配置对象,指定 Redis 的连接信息。
import org.redisson.Redisson; import org.redisson.config.Config; public class RedissonConfig { public static RedissonClient getRedissonClient() { Config config = new Config(); // 单机模式 config.useSingleServer().setAddress("redis://127.0.0.1:6379"); // 主从模式 // config.useMasterSlaveServers().setMasterAddress("redis://127.0.0.1:6379").addSlaveAddress("redis://127.0.0.1:6380"); // 哨兵模式 // config.useSentinelServers().addSentinelAddress("redis://127.0.0.1:26379", "redis://127.0.0.1:26380", "redis://127.0.0.1:26381").setMasterName("mymaster"); // 集群模式 // config.useClusterServers().addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001", "redis://127.0.0.1:7002"); // 如果 Redis 设置了密码,需要配置密码 // config.useSingleServer().setPassword("your_redis_password"); RedissonClient redisson = Redisson.create(config); return redisson; } public static void main(String[] args) { RedissonClient redisson = getRedissonClient(); System.out.println("Redisson is connected: " + redisson.isShutdown()); redisson.shutdown(); // 关闭 Redisson 客户端 } }
解释一下:
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
指定 Redis 的单机地址。config.useMasterSlaveServers()
、config.useSentinelServers()
、config.useClusterServers()
分别用于配置主从、哨兵、集群模式。config.useSingleServer().setPassword("your_redis_password");
如果你的 Redis 设置了密码,需要在这里配置。Redisson.create(config);
根据配置创建 Redisson 客户端。redisson.shutdown();
使用完毕后,记得关闭 Redisson 客户端,释放资源。
-
使用 Redisson 对象
现在,你可以使用 Redisson 提供的各种对象了。
import org.redisson.api.*; public class RedissonExample { public static void main(String[] args) { RedissonClient redisson = RedissonConfig.getRedissonClient(); // 获取一个分布式锁 RLock lock = redisson.getLock("myLock"); try { // 尝试获取锁,最多等待 10 秒,如果获取到锁,则 30 秒后自动释放锁 boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS); if (isLocked) { try { // 业务逻辑 System.out.println("Got the lock! Doing some work..."); Thread.sleep(5000); // 模拟业务处理 } finally { // 释放锁 lock.unlock(); System.out.println("Released the lock!"); } } else { System.out.println("Failed to get the lock!"); } } catch (InterruptedException e) { e.printStackTrace(); } // 获取一个分布式 Map RMap<String, String> map = redisson.getMap("myMap"); map.put("key1", "value1"); String value = map.get("key1"); System.out.println("Value from map: " + value); // 获取一个分布式计数器 RAtomicLong atomicLong = redisson.getAtomicLong("myCounter"); atomicLong.incrementAndGet(); long counterValue = atomicLong.get(); System.out.println("Counter value: " + counterValue); redisson.shutdown(); } }
解释一下:
redisson.getLock("myLock");
获取一个名为 “myLock” 的分布式锁。lock.tryLock(10, 30, TimeUnit.SECONDS);
尝试获取锁,最多等待 10 秒,如果获取到锁,则 30 秒后自动释放锁。lock.unlock();
释放锁。redisson.getMap("myMap");
获取一个名为 “myMap” 的分布式 Map。map.put("key1", "value1");
向 Map 中添加键值对。map.get("key1");
从 Map 中获取值。redisson.getAtomicLong("myCounter");
获取一个名为 “myCounter” 的分布式计数器。atomicLong.incrementAndGet();
原子地增加计数器的值。atomicLong.get();
获取计数器的值。
小总结
Redisson 就像一个 Redis 的“百宝箱”,里面装满了各种好用的 Java 对象,可以帮你轻松搞定分布式锁、分布式集合、分布式队列等等。 🚀 用了 Redisson,你就可以少写很多代码,把更多精力放在业务逻辑上,提高开发效率。 🤩 而且,Redisson 基于 Redis 的高性能,所以你的应用也能跑得飞快! 💨 总之,Redisson 是一个值得尝试的 Redis 客户端,可以让你在分布式开发的道路上事半功倍! 💪
二、Redisson的可重入锁
可重入锁 (Reentrant Lock) - 线程的“VIP 通行证”! 👑
可重入锁,顾名思义,就是可以被同一个线程多次获取的锁。 🔑 想象一下,你是一个 VIP 客户,拥有专属的“通行证”,可以多次进入 VIP 区域,而不需要重新排队! 这种锁允许线程在已经持有锁的情况下,再次获取该锁,而不会被阻塞。
为什么需要可重入锁? - 避免“自己把自己锁死”的尴尬! 🤦♀️
考虑以下场景:
public class MyService {
private RLock lock = redisson.getLock("myLock");
public void methodA() {
lock.lock(); // 获取锁,就像进入 VIP 区域
try {
System.out.println("Method A: Doing some work...");
methodB(); // 调用 methodB,需要再次进入 VIP 区域
} finally {
lock.unlock(); // 释放锁,离开 VIP 区域
}
}
public void methodB() {
lock.lock(); // 再次获取锁,尝试再次进入 VIP 区域
try {
System.out.println("Method B: Doing some work...");
} finally {
lock.unlock(); // 释放锁,离开 VIP 区域
}
}
}
在这个例子中,methodA()
和 methodB()
都使用了同一个锁。 如果锁不是可重入的,那么当 methodA()
调用 methodB()
时,methodB()
会尝试再次获取锁,但由于锁已经被 methodA()
持有,methodB()
会一直等待,导致死锁! 💀 就像你进入 VIP 区域后,又想再次进入,却被告知需要重新排队,把自己堵在了里面!
而如果锁是可重入的,那么当 methodA()
调用 methodB()
时,methodB()
可以成功获取锁,因为锁已经被当前线程持有,就像你拥有 VIP 通行证,可以自由出入 VIP 区域! 🥳
Redisson 可重入锁的使用 - 默认就是 VIP 待遇! 😎
Redisson 默认提供的锁就是可重入锁,所以使用起来非常简单,无需额外配置,直接享受 VIP 待遇!
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
public class RedissonReentrantLockExample {
public static void main(String[] args) throws InterruptedException {
RedissonClient redisson = RedissonConfig.getRedissonClient();
// 获取一个可重入锁,就像获得一张 VIP 通行证! 🎫
RLock lock = redisson.getLock("myLock");
// 线程 1,就像一个 VIP 客户
new Thread(() -> {
try {
lock.lock(); // 获取锁,进入 VIP 区域
System.out.println(Thread.currentThread().getName() + ": Thread 1 acquired the lock.");
Thread.sleep(2000); // 模拟业务处理,享受 VIP 服务
lock.lock(); // 再次获取锁 (可重入),再次进入 VIP 区域
System.out.println(Thread.currentThread().getName() + ": Thread 1 re-acquired the lock.");
Thread.sleep(2000); // 模拟业务处理,继续享受 VIP 服务
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁,离开 VIP 区域
lock.unlock(); // 再次释放锁,确保完全离开 VIP 区域
System.out.println(Thread.currentThread().getName() + ": Thread 1 released the lock.");
}
}, "Thread-1").start();
// 线程 2,就像一个普通客户,需要等待 VIP 客户离开
new Thread(() -> {
try {
Thread.sleep(500); // 稍微等待一下,确保线程 1 先获取锁
lock.lock(); // 获取锁,尝试进入 VIP 区域
System.out.println(Thread.currentThread().getName() + ": Thread 2 acquired the lock.");
Thread.sleep(2000); // 模拟业务处理,享受 VIP 服务
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁,离开 VIP 区域
System.out.println(Thread.currentThread().getName() + ": Thread 2 released the lock.");
}
}, "Thread-2").start();
Thread.sleep(10000); // 等待线程执行完毕
redisson.shutdown();
}
}
代码解释 - 就像一份 VIP 服务指南! 🗺️
lock.lock();
:获取锁,如果锁已经被其他线程持有,当前线程会阻塞,直到获取到锁。lock.unlock();
:释放锁,需要释放相同次数才能真正释放锁,确保完全离开 VIP 区域。
Redisson 可重入锁的底层实现 - Redis Hash 的巧妙运用! 🧮
Redisson 可重入锁的底层实现主要依赖 Redis 的 Hash 数据结构,就像一个精密的“计数器”,记录每个线程的重入次数。
-
Hash 存储锁的信息 - 记录每个 VIP 客户的访问次数! 🔢:Redisson 使用 Hash 来存储锁的信息,key 是锁的名称 (例如 “myLock”),Hash 的 field 是线程 ID,value 是重入次数。
myLock: { "thread-1": 2 // 线程 1 重入了 2 次,享受了 2 次 VIP 服务 }
-
获取锁 - 检查 VIP 资格,并增加访问次数! ✅:当一个线程尝试获取锁时,Redisson 会先判断 Hash 中是否存在该线程的 ID。
- 如果不存在,表示该线程第一次获取锁,Redisson 会在 Hash 中添加该线程的 ID,并将重入次数设置为 1,就像第一次进入 VIP 区域,需要注册并记录访问次数。
- 如果存在,表示该线程已经持有锁,Redisson 会将该线程的重入次数加 1,就像再次进入 VIP 区域,只需要增加访问次数即可。
-
释放锁 - 减少访问次数,直到完全离开! 🚪:当一个线程释放锁时,Redisson 会先判断 Hash 中是否存在该线程的 ID。
- 如果不存在,表示该线程没有持有锁,不能释放锁,就像没有 VIP 资格,无法离开 VIP 区域。
- 如果存在,Redisson 会将该线程的重入次数减 1。 如果重入次数减为 0,Redisson 会从 Hash 中删除该线程的 ID,就像完全离开 VIP 区域,需要注销 VIP 资格。
-
Lua 脚本保证原子性 - 确保操作的完整性! 🔒:Redisson 使用 Lua 脚本将获取锁、释放锁、更新重入次数等操作打包成一个原子操作,保证操作的原子性,就像一个事务,要么全部成功,要么全部失败。
小总结
Redisson 的可重入锁就像一个“VIP 通行证”,允许同一个线程多次进入临界区,而不需要排队等待,避免了“自己把自己锁死”的尴尬! 👑 它利用 Redis 的 Hash 数据结构和 Lua 脚本,实现了高效、可靠的可重入锁。 有了 Redisson 的可重入锁,你就可以轻松地处理复杂的并发场景,避免死锁的发生,让你的线程享受 VIP 待遇! 🥳
三、联锁 (MultiLock) 和红锁(RedLock)
1. 联锁 (MultiLock) - 团队协作,步调一致! 🤝
联锁,就像一个团队执行任务,需要所有成员都同意才能行动! 👨👩👧👦 它把多个独立的锁捆绑在一起,形成一个更强大的“锁联盟”。 只有当所有锁都成功获取,才能真正获得“通行证”,进入临界区执行操作。 🚦
为什么需要联锁?
- 原子性操作的守护神! 🛡️ 想象一下,你需要同时更新多个数据库的记录,必须保证要么全部成功,要么全部失败。 联锁就像一个事务管理器,确保这些操作要么一起完成,要么一起回滚,绝不允许出现中间状态! 🙅♀️
- 锁粒度的放大镜! 🔎 如果你需要保护多个密切相关的资源,一个个加锁太麻烦了! 联锁可以把它们打包成一个更大的“资源包”,一次性锁定,减少锁的竞争,提高效率! 🚀
Redisson 联锁的使用 - 简单易上手! 👍
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.RedissonMultiLock;
import java.util.concurrent.TimeUnit;
public class RedissonMultiLockExample {
public static void main(String[] args) throws InterruptedException {
RedissonClient redisson = RedissonConfig.getRedissonClient();
// 获取三个独立的锁,就像找到三个可靠的队友! 🧑🤝🧑
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");
// 创建联锁,组建一个强大的团队! 💪
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2, lock3);
try {
// 尝试获取联锁,等待团队成员到位! ⏳
boolean isLocked = multiLock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
try {
// 业务逻辑,团队协作,高效完成任务! 🎯
System.out.println("Got the multiLock! Doing some work...");
Thread.sleep(5000); // 模拟业务处理
} finally {
// 释放联锁,任务完成,解散团队! 👋
multiLock.unlock();
System.out.println("Released the multiLock!");
}
} else {
// 获取联锁失败,团队成员未到位,任务取消! ❌
System.out.println("Failed to get the multiLock!");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
redisson.shutdown();
}
}
}
代码解读 - 就像阅读一份清晰的团队章程! 📜
redisson.getLock("lock1");
、redisson.getLock("lock2");
、redisson.getLock("lock3");
:分别获取三个独立的锁,每个锁代表一个需要保护的资源。new RedissonMultiLock(lock1, lock2, lock3);
:创建一个联锁,将三个锁组合成一个整体,只有当所有锁都获取成功,才能执行后续操作。multiLock.tryLock(10, 30, TimeUnit.SECONDS);
:尝试获取联锁,最多等待 10 秒,如果获取到联锁,则在 30 秒后自动释放联锁。multiLock.unlock();
:释放联锁,会自动释放所有被锁定的锁,确保资源得到释放。
2. 红锁 (RedLock) - 多重保险,高可用保障! 🔴
红锁,就像给你的数据加上了多重保险,即使部分 Redis 实例发生故障,也能保证锁的可用性! 🛡️ 它需要在多个独立的 Redis 实例上尝试获取锁,只有当超过半数的实例获取成功,才认为获取锁成功。 就像一个需要多个签名才能生效的合同,确保万无一失! 📝
为什么需要红锁?
- 高可用性的守护者! 🦸♂️ 在单 Redis 实例或者主从 Redis 架构中,一旦 Redis 实例宕机,锁就失效了! 红锁通过在多个独立的 Redis 实例上获取锁,即使部分实例发生故障,锁仍然可用,保证业务的连续性! 🚀
- 脑裂问题的终结者! 🧠 在主从 Redis 架构中,如果发生网络分区 (脑裂),可能会出现多个主节点,导致多个客户端同时获取到锁! 红锁通过在多个独立的 Redis 实例上获取锁,可以有效防止脑裂导致的并发问题! 🚫
Redisson 红锁的使用 - 部署略复杂,但更可靠! ⚙️
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.RedissonRedLock;
import java.util.concurrent.TimeUnit;
public class RedissonRedLockExample {
public static void main(String[] args) throws InterruptedException {
// 连接到三个独立的 Redis 实例,就像找到三个可靠的备份! 💾 💾 💾
RedissonClient redisson1 = RedissonConfig.getRedissonClient(); // 连接到 Redis 实例 1
RedissonClient redisson2 = RedissonConfig.getRedissonClient(); // 连接到 Redis 实例 2
RedissonClient redisson3 = RedissonConfig.getRedissonClient(); // 连接到 Redis 实例 3
// 获取多个锁 (每个 Redis 实例一个锁),就像在多个银行都存了钱! 💰 💰 💰
RLock lock1 = redisson1.getLock("myLock");
RLock lock2 = redisson2.getLock("myLock");
RLock lock3 = redisson3.getLock("myLock");
// 创建红锁,组成一个强大的“锁联盟”,需要多数成员同意才能生效! 🤝
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
try {
// 尝试获取红锁,等待多数 Redis 实例确认! ⏳
boolean isLocked = redLock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
try {
// 业务逻辑,安全可靠地执行任务! ✅
System.out.println("Got the redLock! Doing some work...");
Thread.sleep(5000); // 模拟业务处理
} finally {
// 释放红锁,任务完成,释放所有锁! 👋
redLock.unlock();
System.out.println("Released the redLock!");
}
} else {
// 获取红锁失败,多数 Redis 实例未确认,任务取消! ❌
System.out.println("Failed to get the redLock!");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 关闭所有 Redisson 客户端,释放资源! 🧹
redisson1.shutdown();
redisson2.shutdown();
redisson3.shutdown();
}
}
}
红锁的注意事项 - 使用前请仔细阅读! ⚠️
- 独立的 Redis 实例是前提! ☝️ 红锁必须在多个独立的 Redis 实例上运行,不能使用主从 Redis 架构,否则无法保证高可用性。
- 奇数个 Redis 实例是最佳选择! ✌️ Redis 实例的数量应该选择奇数,例如 3 个、5 个、7 个等,这样可以避免出现平票的情况,确保锁的决策能够达成一致。
- 网络延迟是潜在的风险! ⚡️ 红锁的性能受到网络延迟的影响,因为需要在多个 Redis 实例上进行通信。 因此,需要选择网络状况良好的 Redis 实例,并尽量减少网络延迟。
小总结
联锁就像一个“团队协作”,需要所有成员都同意才能行动,适用于需要原子性操作多个资源的场景。 🤝 红锁就像一个“多重保险”,在多个 Redis 实例上获取锁,提高锁的可用性和容错性,适用于对高可用性要求极高的场景。 🛡️ 选择哪种锁取决于你的具体需求和场景,请根据实际情况进行选择! 🤔
四、锁重试和Watch机制
1. 锁重试机制 (Lock Retry Mechanism) - 永不放弃的追锁者! 🏃♀️
当一个线程尝试获取 Redisson 分布式锁时,如果锁已经被其他线程“捷足先登”了,它不会灰心丧气,而是会化身成一个“永不放弃的追锁者”,不断尝试再次获取锁! 🔄 就像一个锲而不舍的销售员,一次次敲开客户的门,直到成功签下订单! 💼
为什么需要锁重试机制?
- 提高锁的命中率! 🎯 在高并发的场景下,锁的竞争非常激烈,一次尝试就放弃,成功的概率太低了! 重试机制就像一个“幸运buff”,增加线程获取锁的机会,让它更有可能“中奖”! 🍀
- 减少线程上下文切换的开销! 💰 线程获取锁失败后立即进入阻塞状态,会导致频繁的上下文切换,消耗大量的系统资源! 重试机制就像一个“缓冲垫”,让线程在一段时间内继续尝试,避免不必要的阻塞和切换,节省资源! ⛽️
Redisson 的锁重试机制是如何工作的? - 像一个有策略的猎人! 🏹
Redisson 提供了多种获取锁的方法,其中 tryLock(long waitTime, long leaseTime, TimeUnit unit)
方法就巧妙地运用了锁重试机制。 就像一个有策略的猎人,不会盲目追逐猎物,而是会耐心等待,伺机而动! 🦊
具体流程如下:
- 初次尝试,一触即发! 💥 线程首先尝试使用
SETNX
命令在 Redis 中创建锁,就像猎人扣动扳机,希望一击命中! - 成败在此一举! 🤞 如果
SETNX
命令返回 1,表示获取锁成功,就像猎人成功捕获猎物,满载而归! 🏆 流程结束。 - 耐心等待,伺机而动! ⏳ 如果
SETNX
命令返回 0,表示获取锁失败,就像猎人没有击中猎物,需要耐心等待下一次机会。 线程会等待一段时间 (例如几毫秒),就像猎人屏住呼吸,等待猎物再次出现。 - 再次尝试,永不放弃! 💪 等待一段时间后,线程会再次尝试使用
SETNX
命令获取锁,就像猎人再次瞄准,准备射击。 - 循环往复,直到成功或放弃! ♻️ 线程会重复执行步骤 2-4,直到成功获取锁,或者等待时间超过了
waitTime
,就像猎人不断尝试,直到捕获猎物,或者时间耗尽,不得不放弃。
锁重试机制的参数 - 就像猎人的装备! 🎒
waitTime
:最大等待时间,就像猎人的耐心,决定了最多等待多久。 超过这个时间,线程就会放弃获取锁,就像猎人不得不放弃追逐猎物。sleepTime
:每次重试之间的时间间隔,就像猎人每次等待的时间,可以自定义,默认是 15000 / 3 毫秒。
2. Watch Dog 机制 (Watch Dog Mechanism) - 忠诚的锁守护者! 🐶
Watch Dog 机制是 Redisson 分布式锁的“秘密武器”,它像一个忠诚的狗狗,时刻守护着锁的“安全”,防止锁被意外释放! 🐕
为什么需要 Watch Dog 机制?
- 防止锁的“意外死亡”! ⚰️ 如果持有锁的线程在锁的过期时间之前没有完成任务,Redis 会自动释放锁,导致其他线程可以获取到锁,引发并发问题! Watch Dog 机制就像一个“生命药水”,定期给锁续命,防止它“意外死亡”! 🧪
- 保证任务的“顺利完成”! ✅ Watch Dog 机制可以自动延长锁的过期时间,确保持有锁的线程有足够的时间完成任务,就像给线程提供了一个“无限时工作许可证”,让它安心工作,不用担心时间不够! ⏰
Redisson 的 Watch Dog 机制是如何工作的? - 像一个尽职尽责的保姆! 🤱
- 启动 Watch Dog 线程,开始守护! 🚀 当线程成功获取锁后,Redisson 会启动一个 Watch Dog 线程,就像给锁安排了一个尽职尽责的保姆,时刻守护着它。
- 定期巡查,时刻关注! 👀 Watch Dog 线程会定期 (默认是过期时间的 1/3) 检查当前线程是否还持有锁,就像保姆定期巡查,确保孩子安全无恙。
- 自动续期,延长寿命! ➕ 如果当前线程还持有锁,Watch Dog 线程会使用
EXPIRE
命令自动续期锁的过期时间,延长锁的“寿命”,就像保姆给孩子喂奶,补充能量。
Watch Dog 机制的参数 - 就像保姆的工具箱! 🧰
lockWatchdogTimeout
:锁的过期时间,默认是 30 秒,就像保姆的“工作时间”,可以通过Config
对象的setLockWatchdogTimeout()
方法进行配置。
Watch Dog 机制的原理 - 就像一个聪明的管家! 🧠
Redisson 使用 Lua 脚本来实现 Watch Dog 机制,Lua 脚本会判断当前线程是否还持有锁,如果持有锁,则自动续期锁的过期时间,就像一个聪明的管家,能够自动处理各种事务,保证家庭的正常运转。
小总结
锁重试机制就像一个“永不放弃的追锁者”,不断尝试获取锁,提高锁的命中率。 🏃♀️ Watch Dog 机制就像一个“忠诚的锁守护者”,定期续期锁的过期时间,防止锁被意外释放。 🐕 这两个机制就像一对“黄金搭档”,共同保障了 Redisson 分布式锁的可靠性和稳定性,让你可以安心使用它来构建并发安全的分布式应用! 🎉
五、总结
- 分布式锁: 解决分布式系统中多个节点同时访问共享资源时的并发问题,保证数据一致性。 就像交通信号灯,确保车辆有序通行,避免交通堵塞! 🚦
- 可重入锁: 允许同一个线程多次获取同一个锁,避免死锁的发生。 就像 VIP 通行证,允许 VIP 客户多次进入 VIP 区域,无需重新排队! 👑
- 锁重试机制: 当获取锁失败时,线程不会立即放弃,而是会不断尝试,提高获取锁的成功率。 就像永不放弃的追锁者,锲而不舍,直到成功! 🏃♀️
- Watch Dog 机制: 自动续期锁的过期时间,防止锁被意外释放,保证业务的连续性。 就像忠诚的锁守护者,时刻守护着锁的安全,防止锁“意外死亡”! 🐶
- 联锁 (MultiLock): 同时锁定多个锁,保证多个资源的原子性操作。 就像团队协作,需要所有成员都同意才能行动! 🤝
- 红锁 (RedLock): 在多个独立的 Redis 实例上获取锁,提高锁的可用性和容错性。 就像多重保险,即使部分 Redis 实例发生故障,也能保证锁的可用性! 🛡️