日常记录:简单高效的实现一个基于Redission的阻塞队列
配置
@Configuration
public class RedissonQueueConfig {
private static final String queueName = "queueName";
@Resource
private RedissonClient redissonClient;
@Bean("xxxBlockingQueue")
public RBlockingQueue<String> blockingQueue() {
return redissonClient.getBlockingQueue(queueName);
}
@Bean("xxxDelayedQueue")
public RDelayedQueue<String> delayedQueue(RBlockingQueue<String> blockQueue) {
return redissonClient.getDelayedQueue(blockQueue);
}
}
生产
@Component
public class producer {
@Resource
private RDelayedQueue<String> xxxDelayQueue;
public void offer(){
delayedQueue.offerAsync("hello world", 20, TimeUnit.SECONDS);
}
}
消费
@Slf4j
@Component
public class ConsumerTask {
@Resource
private RBlockingQueue<Object> xxxblockingQueue;
@PostConstruct
public void take() {
new Thread(() -> {
while (true) {
try {
log.info(blockingQueue.take().toString());
//20秒后输出hello world
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
原理
首先创建了一个Redisson实现的阻塞队列RBlockingQueue的实例blockingQueue,然后又使用该阻塞队列blockingQueue创建了一个延时队列RDelayedQueue的实例delayedQueue。
延时消息添加后并不是立即进入到阻塞队列blockingQueue中,而是到达了设定的延时时间(满足延时策略)之后才会从延时队列delayedQueue进入到阻塞队列blockingQueue;
延时消息的添加由延时队列delayedQueue完成;
而延时队列的消费则由阻塞队列blockingQueue完成。