整合redisson作为分布式锁等功能框架
1)引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
2)配置redisson
@Configuration
public class MyRedissonConfig {
/**
* 所有对redisson的使用都是通过RedissonClient对象
*
* @return
* @throws IOException
*/
@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
//创建配置
Config config = new Config();
config.useSingleServer().setAddress("redis://主机地址:6379");//单节点
//2.根据Config创建出RedissonClient
return Redisson.create(config);
}
}
3)使用 参考官方文档: https://github.com/redisson/redisson/wiki
值得注意的是:基于Redis的Redisson分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
RLock lock = redisson.getLock("anyLock");
// 最常见的使用方法
lock.lock();
- 测试redisson分布式锁
浏览器二个窗口先后发送二次请求 /hello
结论:其他线程想要获取锁 必须等待 是一种阻塞式等待 等待上一个获取锁的线程释放锁后 方可获取到锁,执行业务
通过redis客户端连接工具我们可以看到锁的ttl(过期时间) 会自动续期
@ResponseBody
@GetMapping("/hello")
public String hello(){
//获取锁
RLock lock = redissonClient.getLock("my-lock");
//加锁
lock.lock();//其他线程想要获取锁 必须等待 是一种阻塞式等待
//1)、redissonClient锁的自动续期 如果业务运行时间超长,运行期间自动给锁的ttl(过期时间)续期,不用担心业务时间执行过长,导致锁被自动删除
//2)、加锁的业务只要执行完成,就不会给当前锁续期 即使不手动解锁 锁也会在ttl时间过后 也会删除锁 ---》防止死锁
try {
System.out.println("加锁成功,执行业务。。。。"+Thread.currentThread().getId());
TimeUnit.SECONDS.sleep(3);
}catch (Exception e){
}finally {
System.out.println("释放锁....."+Thread.currentThread().getId());
lock.unlock();
}
return "hello";
}
测试代码2:
@ResponseBody
@GetMapping("/hello2")
public String hello2(){
//获取锁
RLock lock = redissonClient.getLock("my-lock2");
lock.lock(10, TimeUnit.SECONDS);//在锁时间到了以后 不会再自动续期 10s以后自动解锁 注意!!自动解锁的时间一定要大于业务的执行时间
//-------------------------------------------------------------------------
//1.如果我们传递了锁的超时时间,就会发送给redis执行脚本,进行占锁 默认超时就是我们指定的时间
//2.如果我们未指定锁的超时时间 默认的超时时间是30s [LockWatchdogTimeOut 看门狗的默认时间];
//只要占锁成功 就会启动一个定时任务【重新设置过期时间,新的过期时间就是看看门狗的默认时间 】 每隔10s都会自动续期
//internalLockLeaseTime/3 ,10s
//推荐使用
//1).lock.lock(10, TimeUnit.SECONDS);
try {
System.out.println("加锁成功,执行业务。。。。"+Thread.currentThread().getId());
Thread.sleep(30000);
}catch (Exception e){
}finally {
System.out.println("释放锁....."+Thread.currentThread().getId());
lock.unlock();
}
return "hello2";
}
总结:基于Redis的Redisson分布式锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。用法和juc包下的各种锁用法基本一致 ReadWriteLock,信号量(Semaphore),可重入锁(Reentrant Lock),闭锁(CountDownLatch)等
官网都有解释:更多细节请参考官网:https://github.com/redisson/redisson/wiki