服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java 延迟队列的常用的实现方式

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

2021-09-01 10:57废物大师兄 Java教程

这篇文章主要介绍了Java 延迟队列的常用的实现方式,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下

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

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

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

。。。

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

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

1.  DelayQueue

首先,定义一个延迟任务

  1. package com.cjs.example;
  2.  
  3. import lombok.Data;
  4.  
  5. import java.util.concurrent.Delayed;
  6. import java.util.concurrent.TimeUnit;
  7.  
  8. /**
  9. * @author ChengJianSheng
  10. * @since 2021/3/18
  11. */
  12. @Data
  13. public class DelayTask implements Delayed {
  14.  
  15. private Long orderId;
  16.  
  17. private long expireTime;
  18.  
  19. public DelayTask(Long orderId, long expireTime) {
  20. this.orderId = orderId;
  21. this.expireTime = expireTime;
  22. }
  23.  
  24. @Override
  25. public long getDelay(TimeUnit unit) {
  26. return expireTime - System.currentTimeMillis();
  27. }
  28.  
  29. @Override
  30. public int compareTo(Delayed o) {
  31. return (int) (getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
  32. }
  33.  
  34. }

然后,定义一个管理类

  1. package com.cjs.example;
  2.  
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.CommandLineRunner;
  6. import org.springframework.stereotype.Component;
  7.  
  8. import java.util.concurrent.DelayQueue;
  9. import java.util.concurrent.ExecutorService;
  10. import java.util.concurrent.Executors;
  11.  
  12. /**
  13. * @author ChengJianSheng
  14. * @since 2021/3/19
  15. */
  16. @Slf4j
  17. @Component
  18. public class DelayQueueManager implements CommandLineRunner {
  19.  
  20. private DelayQueue<DelayTask> queue = new DelayQueue<>();
  21.  
  22. @Autowired
  23. private ParkOrderQueryHandler handler;
  24.  
  25. @Override
  26. public void run(String... strings) throws Exception {
  27. ExecutorService executorService = Executors.newSingleThreadExecutor();
  28. executorService.execute(new Runnable() {
  29. @Override
  30. public void run() {
  31. while (true) {
  32. try {
  33. DelayTask task = queue.take();
  34. handler.handle(task);
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. });
  41. }
  42.  
  43. public void put(DelayTask task) {
  44. queue.put(task);
  45. }
  46. }

插入任务

  1. @Slf4j
  2. @Service
  3. public class PayServiceImpl implements PayService {
  4.  
  5. @Autowired
  6. private DelayQueueManager delayQueueManager;
  7.  
  8. @Override
  9. public void pay() {
  10.  
  11. delayQueueManager.put(new DelayTask(1, 15));
  12. delayQueueManager.put(new DelayTask(2, 30));
  13. delayQueueManager.put(new DelayTask(3, 60));
  14.  
  15. }
  16. }

2.  Redis Key过期回调

修改redis.conf文件

# bind 127.0.0.1 -::1
protected-mode no
notify-keyspace-events Ex

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

  1. [root@localhost redis-6.2.1]$ src/redis-server redis.conf
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <parent>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-parent</artifactId>
  9. <version>2.4.4</version>
  10. <relativePath/> <!-- lookup parent from repository -->
  11. </parent>
  12. <groupId>com.example</groupId>
  13. <artifactId>demo0401</artifactId>
  14. <version>0.0.1-SNAPSHOT</version>
  15. <name>demo0401</name>
  16. <description>Demo project for Spring Boot</description>
  17. <properties>
  18. <java.version>1.8</java.version>
  19. </properties>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-data-redis</artifactId>
  24. </dependency>
  25. </dependencies>
  26.  
  27. <build>
  28. <plugins>
  29. <plugin>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-maven-plugin</artifactId>
  32. </plugin>
  33. </plugins>
  34. </build>
  35.  
  36. </project>

RedisConfig.java

  1. package com.example.config;
  2.  
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.data.redis.connection.RedisConnectionFactory;
  6. import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  7.  
  8. /**
  9. * @author ChengJianSheng
  10. * @since 2021/4/2
  11. */
  12. @Configuration
  13. public class RedisConfig {
  14.  
  15. @Bean
  16. public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
  17. RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  18. container.setConnectionFactory(connectionFactory);
  19. return container;
  20. }
  21. }

创建一个监听类

  1. package com.example.listener;
  2.  
  3. import org.springframework.data.redis.connection.Message;
  4. import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
  5. import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  6. import org.springframework.stereotype.Component;
  7.  
  8. /**
  9. * @author ChengJianSheng
  10. * @since 2021/4/2
  11. */
  12. @Component
  13. public class MyRedisKeyExpirationListener extends KeyExpirationEventMessageListener {
  14.  
  15. public MyRedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
  16. super(listenerContainer);
  17. }
  18.  
  19. @Override
  20. public void onMessage(Message message, byte[] pattern) {
  21. String expiredKey = message.toString();
  22. System.out.println("监听到Key: " + expiredKey + " 已过期");
  23. }
  24. }

3.  RocketMQ

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

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

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

原文链接:https://www.cnblogs.com/cjsblog/p/14612169.html

延伸 · 阅读

精彩推荐