1、引入
1、加入Redisson依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.33.0</version>
</dependency>
2、创建配置类
/**
* @Author: js
* @Date: 2024/8/23
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedissonConfig {
private String host;
private String port;
private String password;
private Integer database;
private static final String ADDRESS_PREFIX = "redis://";
private static final Integer TIMEOUT = 3000;
//创建Redisson配置类
@Bean
RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress(ADDRESS_PREFIX + host + ":" + port)
.setPassword(password)
.setDatabase(database)
.setTimeout(TIMEOUT);
return Redisson.create(config);
}
}
到这里就引入了redisson,可以使用分布式锁了
2、分布式锁的使用
@GetMapping("/test2")
public String test2() {
//创建lock对象,lock-test02保证每个方法 唯一
RLock lock = redissonClient.getLock("lock-test02");
try {
//有四个方法
//1、尝试获取锁,获取不到锁就阻塞式等待,获取到之后默认过期时间30S , 默认看门狗机制,减少10秒就会看下代码有没后执行完,没有就自动续期
//lock.lock();
//2、自己设置锁过期时间,没有Watch Dog,其他线程阻塞式等待,一直到这个线程释放锁或者锁过期
// lock.lock(10, TimeUnit.SECONDS);
//3、尝试获取锁,最大等待时间为5秒,获取不到就返回false
// 返回true 代表获取到锁.没有Watch Dog,过期时间10秒
// boolean tried = lock.tryLock(5, 10, TimeUnit.SECONDS);
// if (tried){
// System.out.println("或取到锁");
// TimeUnit.SECONDS.sleep(20);
// }else {
// System.out.println("5秒钟到了,放弃获取锁");
// return "放弃";
// }
//4、尝试获取锁10秒,获取到返回true,没有获取到返回false ,有Watch Dog,
boolean tryLock = lock.tryLock(10, TimeUnit.SECONDS);
if (tryLock){
//获取到锁
System.out.println("或取到锁");
TimeUnit.SECONDS.sleep(20);
}else {
//没有到锁
System.out.println("10秒钟到了,放弃获取锁");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("异常");
} finally {
//释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("释放锁");
} else {
System.out.println("锁过期,或没有锁,不用释放");
}
}
return UUID.randomUUID().toString() + new Date();
}
3、延时队列使用
1、创建队列bean(在方法里面new也行,这里直接创建好,交给spring容器管理)
@Component
@RequiredArgsConstructor
public class RedissonConfigQueue {
private final RedissonClient redissonClient;
private final static String queueName = "orderQueue";
/**
* 创建一个阻塞队列
*/
public RBlockingQueue<Object> blockingQueue() {
return redissonClient.getBlockingQueue(queueName);
}
/**
* 延时队列
* 阻塞队列放到延迟队列里面,消息放在延迟队列里面,时间到后 消息投递到阻塞队列,消费者监听阻塞队列
*/
public RDelayedQueue<Object> getDelayedQueue(RBlockingQueue<Object> blockQueue) {
return redissonClient.getDelayedQueue(blockQueue);
}
}
2、生产者投递消息
@GetMapping("/test")
public String test() {
redissonConfigQueue.getDelayedQueue(redissonConfigQueue.blockingQueue())
.offer("我是消息", 600, TimeUnit.SECONDS);//消息内容,延时时间,时间单位(秒)
return UUID.randomUUID().toString();
}
3、消费者监听消费消息
@PostConstruct
public void init() {
new Thread(() -> {
while (true) {
try {
//阻塞等待队列内有可消费延时消息,避免无意义的循环占用CPU
String string = redissonConfigQueue.blockingQueue().take().toString();
System.out.println(string);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();
}