Java 延迟队列的常用的实现方式

网友投稿 255 2023-01-23

Java 延迟队列的常用的实现方式

延迟队列的使用场景还比较多,例如:

1、超时未收到支付回调,主动查询支付状态;

2、规定时间内,订单未支付,自动取消;

。。。

总之,但凡需要在未来的某个确定的时间点执行检查的场景中都可以用延迟队列。

常见的手段主要有:定时任务扫描、RocketMQ延迟队列、java自动的延迟队列、监听Redis Key过期等等

1.  DelayQueue

首先,定义一个延迟任务

package com.cjs.example;

import lombok.Data;

import java.util.concurrent.Delayed;

import java.util.concurrent.TimeUnit;

/**

* @author ChengJianSheng

* @since 2021/3/18

*/

@Data

public class DelayTask implements Delayed {

private Long orderId;

private long expireTime;

public DelayTask(Long orderId, long expireTime) {

this.orderId = orderId;

this.expireTime = expireTime;

}

@Override

public long getDelay(TimeUnit unit) {

return expireTime - System.currentTimeMillis();

}

@Override

public int compareTo(Delayed o) {

return (int) (getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));

}

}

然后,定义一个管理类

package com.cjs.example;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.CommandLineRunner;

import org.springframework.stereotype.Component;

import java.util.concurrent.DelayQueue;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

* @author ChengJianSheng

* @since 2021/3/19

*/

@Slf4j

@Component

public class DelayQueueManager implements CommandLineRunner {

private DelayQueue queue = new DelayQueue<>();

@Autowired

private ParkOrderQueryHandler handler;

@Override

public void run(String... strings) throws Exception {

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {

@Override

public void run() {

while (true) {

try {

DelayTask task = queue.take();

handler.handle(task);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

}

public void put(DelayTask task) {

queue.put(task);

}

}

插入任务

@Slf4j

@Service

public class PayServiceImpl implements PayService {

@Autowired

private DelayQueueManager delayQueueManager;

@Override

public void pay() {

delayQueueManager.put(new DelayTask(1, 15));

delayQueueManager.put(new DelayTask(2, 30));

delayQueueManager.put(new DelayTask(3, 60));

}

}

2.  Redis Key过期回调

修改redis.conf文件

# bind 127.0.0.1 -::1

protected-mode no

notify-keyspace-events Ex

[root@localhost redis-6.2.1]$ src/redis-server redis.conf

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.4.4

com.example

demo0401

0.0.1-SNAPSHOT

demo0401

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.boot

spring-boot-maven-plugin

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.4.4

com.example

demo0401

0.0.1-SNAPSHOT

demo0401

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.boot

spring-boot-maven-plugin

RedisConfig.java

package com.example.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.listener.RedisMessageListenerContainer;

/**

* @author ChengJianSheng

* @since 2021/4/2

*/

@Configuration

public class RedisConfig {

@Bean

public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

RedisMessageListenerContainer container = new RedisMessageListenerContainer();

container.setConnectionFactory(connectionFactory);

return container;

}

}

创建一个监听类

package com.example.listener;

import org.springframework.data.redis.chttp://onnection.Message;

import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;

import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import org.springframework.stereotype.Component;

/**

* @author ChengJianSheng

* @since 2021/4/2

*/

@Component

public class MyRedisKeyExpirationListener extends KeyExpirationEventMessageListener {

public MyRedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {

super(listenerContainer);

}

@Override

public void onMessage(Message message, byte[] pattern) {

String expiredKey = message.toString();

System.out.println("监听到Key: " + expiredKey + " 已过期");

}

}

3.  RocketMQ

官方文档:https://help.aliyun.com/document_detail/29549.htm

以上就是Java 延迟队列的常用的实现方式的详细内容,更多关于Java 延迟队列实现方式的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:豆瓣电影api接口的链接(豆瓣api v2 官网)
下一篇:springboot自动装配原理初识
相关文章

 发表评论

暂时没有评论,来抢沙发吧~