文章目录
-
- 写在文章开头
- 详解Redisson 分布式锁使用和实现
-
- 前置准备工作
- 分布式锁的基本使用
- 公平锁的使用
- 联锁的使用
- 读写锁基本使用
- 常见问题
-
- Redisson和Jedis有什么区别
- redisson如何实现分布式锁
- redisson如何实现分布式锁的可重入
- redisson如何实现公平锁
- Redisson的watchdog机制是什么?如何实现的
- 什么是RedLock,其实现思路是什么
- Redisson 中为什么要废弃 RedLock
- 参考
写在文章开头
在当今分布式系统大行其道的技术领域,如何有效协调多个节点之间对共享资源的访问,成了开发者们必须攻克的一道难关。分布式锁,作为解决这一难题的关键技术手段,正发挥着举足轻重的作用。
在众多分布式锁的实现方案中,Redisson 以其强大的功能、出色的性能和极高的易用性脱颖而出,成为了开发者们的得力助手。Redisson 不仅仅是一个简单的分布式锁工具,它更像是一套完整的分布式协调框架,提供了丰富多样的分布式对象和服务,极大地简化了分布式系统的开发过程。
详解Redisson 分布式锁使用和实现
前置准备工作
使用redisson
时我们优先需要引入其依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.5</version>
</dependency>
然后配置redis基本配置信息,这里笔者以单体架构为例给出redis
的配置示例:
spring.redis.host=localhost
spring.redis.port=6379
分布式锁的基本使用
RLock
继承了JUC
包下的Lock
接口,所以使用起来和JUC
包下的几个lock
类似,这里我们也给出相应的基本代码示例:
CountDownLatch countDownLatch = new CountDownLatch(2);
//声明一把分布式锁
RLock lock = redissonClient.getLock("lock");
new Thread(() -> {
try {
//上锁
lock.lock();
log.info("lock lock success");
ThreadUtil.sleep(1, TimeUnit.MINUTES);
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
try {
//休眠5s让上一个线程先取锁
ThreadUtil.sleep(5, TimeUnit.SECONDS);
//上锁
if (lock.tryLock()) {
log.info("try lock success");
//成功后执行业务逻辑然后释放锁
ThreadUtil.sleep(1, TimeUnit.MINUTES);
lock.unlock();
} else {
log.info("try lock fail");
}
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
countDownLatch.await();
对应的输出结果如下,可以看到第一个线程基于redisson
上锁成功后,第二个线程就无法上锁了:
公平锁的使用
默认情况下redisson
分布式锁是非公平的,即任意时刻任意一个请求都可以在锁释放后争抢分布式锁,对此redisson
给出了公平锁的实现,如下代码所示,笔者通过getFairLock
声明一把公平锁,让声明5个线程进行争抢:
int size = 5;
//声明分布式锁
RLock reentrantLock = redissonClient.getFairLock("lock");
//创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(size);
CountDownLatch countDownLatch = new CountDownLatch(size);
//遍历线程池,让池内的线程争抢分布式锁
for (int i = 0; i < size; i++) {
threadPool.submit(() -> {
try {
reentrantLock.lock();
log.info("reentrantLock.lock success");
} catch (Exception e) {
log.error("reentrantLock.lock error", e);
} finally {
reentrantLock.unlock();
log.info("reentrantLock.unlock success");
countDownLatch.countDown();
}
});
}
countDownLatch.await();
可以看到,笔者通过调试的方式顺序让线程争抢分布式锁,最终输出结果也是按照先来后到的方式获取锁和释放锁:
联锁的使用
联锁顾名思义,只有一次性获取多把锁之后才能算成功,对应的代码示例如下:
RLock lock1 = redissonClient.getFairLock