Redisson分布式锁全攻略:用法、场景与要点
目录
1. 普通可重入锁(RLock)
2. 公平锁(RFairLock)
3. 读写锁(RReadWriteLock)
4. 多重锁(RedissonMultiLock)
1. 普通可重入锁(RLock)
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonLockExample {public static void main(String[] args) {// 配置 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 创建 Redisson 客户端实例RedissonClient redisson = Redisson.create(config);// 获取锁实例RLock lock = redisson.getLock("myLock");try {// 尝试获取锁,最多等待 100 秒,锁持有时间为 10 秒boolean isLocked = lock.tryLock(100, 10, TimeUnit.SECONDS);if (isLocked) {// 执行业务逻辑System.out.println("Lock acquired by " + Thread.currentThread().getName());// 模拟业务逻辑处理Thread.sleep(5000);} else {System.out.println("Failed to acquire lock");}} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();System.out.println("Lock released by " + Thread.currentThread().getName());}}// 关闭 Redisson 客户端redisson.shutdown();}
}
应用场景
-
电商秒杀系统:多个用户同时请求购买商品,通过分布式锁确保同一时间只有一个用户能够成功下单。
-
分布式任务调度:多个节点同时运行任务,通过锁确保任务的唯一性。
注释说明
-
tryLock
方法:尝试获取锁,可以指定等待时间和锁的持有时间。 -
isHeldByCurrentThread
方法:检查当前线程是否持有锁,避免误释放。 -
unlock
方法:释放锁,确保在finally
块中调用,防止资源泄漏。
2. 公平锁(RFairLock)
示例代码
import org.redisson.Redisson;
import org.redisson.api.RFairLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonFairLockExample {public static void main(String[] args) {// 配置 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 创建 Redisson 客户端实例RedissonClient redisson = Redisson.create(config);// 获取公平锁实例RFairLock lock = redisson.getFairLock("myFairLock");try {// 尝试获取锁,最多等待 100 秒,锁持有时间为 10 秒boolean isLocked = lock.tryLock(100, 10, TimeUnit.SECONDS);if (isLocked) {// 执行业务逻辑System.out.println("Fair lock acquired by " + Thread.currentThread().getName());// 模拟业务逻辑处理Thread.sleep(5000);} else {System.out.println("Failed to acquire fair lock");}} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();System.out.println("Fair lock released by " + Thread.currentThread().getName());}}// 关闭 Redisson 客户端redisson.shutdown();}
}
应用场景
-
资源分配系统:多个线程或节点请求资源,通过公平锁确保按请求顺序获取资源。
-
队列处理系统:多个消费者处理队列中的任务,确保任务按顺序处理。
注释说明
-
公平锁特点:按照请求顺序获取锁,避免饥饿现象。
-
tryLock
方法:与普通锁类似,但公平锁会按照请求顺序排队。
3. 读写锁(RReadWriteLock)
示例代码
import org.redisson.Redisson;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonReadWriteLockExample {public static void main(String[] args) {// 配置 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 创建 Redisson 客户端实例RedissonClient redisson = Redisson.create(config);// 获取读写锁实例RReadWriteLock readWriteLock = redisson.getReadWriteLock("myReadWriteLock");// 模拟读操作Thread readThread = new Thread(() -> {try {readWriteLock.readLock().lock();System.out.println("Read lock acquired by " + Thread.currentThread().getName());// 模拟读操作Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {readWriteLock.readLock().unlock();System.out.println("Read lock released by " + Thread.currentThread().getName());}});// 模拟写操作Thread writeThread = new Thread(() -> {try {readWriteLock.writeLock().lock();System.out.println("Write lock acquired by " + Thread.currentThread().getName());// 模拟写操作Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {readWriteLock.writeLock().unlock();System.out.println("Write lock released by " + Thread.currentThread().getName());}});// 启动线程readThread.start();writeThread.start();try {readThread.join();writeThread.join();} catch (InterruptedException e) {Thread.currentThread().interrupt();}// 关闭 Redisson 客户端redisson.shutdown();}
}
应用场景
-
缓存系统:多个线程读取缓存,少数线程更新缓存,通过读写锁提高并发性能。
-
数据库查询与更新:多个线程查询数据库,少数线程更新数据库。
注释说明
-
读锁共享:多个线程可以同时获取读锁。
-
写锁独占:写锁获取后,其他线程无法获取读锁或写锁。
-
锁的释放:确保在
finally
块中释放锁,避免死锁。
4. 多重锁(RedissonMultiLock)
示例代码
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.api.RedissonMultiLock;
import org.redisson.config.Config;public class RedissonMultiLockExample {public static void main(String[] args) {// 配置 Redisson 客户端Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");// 创建 Redisson 客户端实例RedissonClient redisson = Redisson.create(config);// 获取多个锁实例RLock lock1 = redisson.getLock("myLock1");RLock lock2 = redisson.getLock("myLock2");// 创建多重锁RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);try {// 尝试获取多重锁,最多等待 100 秒,锁持有时间为 10 秒boolean isLocked = multiLock.tryLock(100, 10, TimeUnit.SECONDS);if (isLocked) {// 执行业务逻辑System.out.println("Multi lock acquired by " + Thread.currentThread().getName());// 模拟业务逻辑处理Thread.sleep(5000);} else {System.out.println("Failed to acquire multi lock");}} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放多重锁if (multiLock.isHeldByCurrentThread()) {multiLock.unlock();System.out.println("Multi lock released by " + Thread.currentThread().getName());}}// 关闭 Redisson 客户端redisson.shutdown();}
}
应用场景
-
分布式事务:多个资源需要同时锁定,确保事务的原子性。
-
复杂业务流程:多个步骤需要分别锁定不同资源,通过多重锁确保整体