引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.2</version>
</dependency>
添加配置
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
// 可以用"rediss://"来启用SSL连接
config.useSingleServer().setAddress("redis://172.16.116.100:6379");
return Redisson.create(config);
}
}
1、描述:
为了避免当前服务器获取到锁,在未解锁之前服务器宕机造成死锁情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout
来另行指定。RLock
对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁,其他进程解锁则会抛出IllegalMonitorStateException
错误。另外Redisson还通过加锁的方法提供了leaseTime
的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
public String checkAndLock(){
//可重入锁
RLock lock = redissonClient.getLock("lock");
//公平锁
//RLock lock = redissonClient.getFairLock("lock");
lock.lock();
//10秒钟后自动解锁
//lock.lock(10,TimeUnit.SECONDS);
/* try{
//尝试枷锁,最多等待时间10秒,自动释放锁时间11秒
boolean b = lock.tryLock(10, 11, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(10);
}catch (Exception e){
e.printStackTrace();
}*/
String stock = stringRedisTemplate.opsForValue().get("stock");
if (Objects.nonNull(stock)&&Integer.valueOf(stock)>0){
Integer value = Integer.valueOf(stock);
stringRedisTemplate.opsForValue().set("stock",(--value).toString());
}
lock.unlock();
return "分布式锁";
}
描述:
基于Redis的Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock
接口的一种RLock
对象。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。
可重入锁获取到锁时随机的,公平锁有队列保存key的顺序,先到先得。
描述
设置的信号量数就是能执行的请求处理个数,类似于线程池,信号量使用完之后,其他请求处理只能等待,直到其他信号量释放。
public void testSemaphore(){
RSemaphore semaphore = redissonClient.getSemaphore("semaphore");
semaphore.trySetPermits(3);
try {
semaphore.acquire();
TimeUnit.SECONDS.sleep(5);
System.out.println(System.currentTimeMillis());
semaphore.release();
}catch (Exception e){
e.printStackTrace();
}
}
@GetMapping("/testLatch")
public String testLatch(){
RCountDownLatch latch = redissonClient.getCountDownLatch("latch");
latch.trySetCount(6);
try{
latch.await();
}catch (Exception e){
e.printStackTrace();
}
return "班长锁门。。。";
}
@GetMapping("/testCountDown")
public String testCountDown(){
RCountDownLatch latch = redissonClient.getCountDownLatch("latch");
latch.trySetCount(6);
latch.countDown();
return "出来了一位同学";
}