`

java中延时队列的使用

阅读更多

     最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅java的api后,发现java中有一个延时队列可以解决这个问题。

实现思路

1、需要延时发送消息的实体类实现 Delayed 接口,在getDelay方法中,返回这个对象还有多上时间需要执行。

2、将短信类加入到延时队列DelayQueye

实现效果:

    将短信Sms加入到队列中,到了invokedTime后从队列中直接取出执行。

    主线程中启动一个子线程,打印当前时间,查看队列中的数据执行的时机是否正确。

    delayqueue 的take方法,获取并移除此队列的头部,在可从此队列获得到期延迟的元素之前一直等待(如有必要)

代码如下

@Slf4j
public class DelayTest {
	@Data
	@Builder
	static class Sms implements Delayed {
		// 执行时间
		private long invokedTime;
		// 需要发出的消息
		private String smg;

		public static Sms build(String msg, int expireTimeSecond) {
			return Sms.builder().smg(msg).invokedTime(System.nanoTime() + TimeUnit.NANOSECONDS.convert(expireTimeSecond, TimeUnit.SECONDS)).build();
		}

		/**
		 * 返回这个对象剩余的延时时间
		 *
		 * @param unit
		 * @return
		 */
		@Override
		public long getDelay(TimeUnit unit) {
			return unit.convert(invokedTime - System.nanoTime(), TimeUnit.NANOSECONDS);
		}

		@Override
		public int compareTo(Delayed o) {
			if (o == null || !(o instanceof Sms))
				return 1;
			if (o == this)
				return 0;
			Sms sms = (Sms) o;
			if (this.invokedTime > sms.invokedTime) {
				return 1;
			} else if (this.invokedTime == sms.invokedTime) {
				return 0;
			} else {
				return -1;
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		DelayQueue<Sms> queue = new DelayQueue<>();
		queue.add(Sms.build("3-hello3", 3));
		queue.add(Sms.build("5-hello5", 5));
		queue.add(Sms.build("2-hello2", 2));
		queue.add(Sms.build("4-hello4", 1));
		queue.add(Sms.build("1-hello1", 1));
		new Thread(() -> {
			Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
				log.info(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
			}, 0, 1, TimeUnit.SECONDS);
		}).start();

		Sms sms;
		while (null != (sms = queue.take())) {
			System.out.println(sms);
		}
	}
}

 执行结果:



 

  • 大小: 36.9 KB
分享到:
评论

相关推荐

    JAVA 实现延迟队列的方法

    JAVA 实现延迟队列的方法是指在 JAVA 中实现延迟队列的方法,即在特定的延迟时间后触发某个事件,这种机制广泛应用于日常开发的场景中,例如用户登录之后5分钟给用户做分类推送、用户多少天未登录给用户做召回推送、...

    一口气说出Java 6种延时队列的实现方法(面试官也得服)

    Java 延时队列的实现方法 延时队列是一种特殊的队列,它可以根据指定的延迟时间来消费队列中的消息。在 Java 中,实现延时队列有多种方式,以下是六种常见的实现方法: 1. DelayQueue 延时队列 DelayQueue 是 ...

    redis的sorted set实现延时队列

    在提供的文件 `delay-queue-node-master` 中,可能是使用 Node.js 编写的 Redis 延时队列实现。通常,这样的实现会包含以下部分: - 初始化 Redis 连接。 - 定义添加任务、获取和处理到期任务、删除任务等方法。 - ...

    java利用delayedQueue实现本地的延迟队列

    DelayQueue 能够保证队列中的对象是有序的,即队头对象的延迟到期时间最长。 DelayQueue 的使用场景非常广泛,如: 1. 订单业务中,下单之后如果三十分钟之内没有付款就自动取消订单。 2. 饿了吗订餐通知中,...

    springboot+rabbitmq实现延时队列

    5. **消息消费**:定义一个`@RabbitListener`注解的消费方法,用于接收并处理延时队列中的消息。这里可以利用Spring的`@ServiceActivator`或`@Bean`定义多个处理策略,通过策略模式选择合适的处理方式。 6. **消费...

    基于Redis实现的延迟消息队列

    整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个Bucket,并将delay...

    redis延时队列.zip

    在这个"redis延时队列.zip"压缩包中,包含两个Java文件:DelayDataConsumer.java和DelayDataProducer.java,它们分别代表了延时队列的消费者和生产者角色。 首先,我们来了解Redis延时队列的基本原理。Redis本身并...

    时间轮算法+延时队列实现任务队列Java Demo

    多层时间轮,可根据配置的时间轮大小参数以及插入任务的相对时间,动态地创建不同层次的时间轮实例(这里的多层时间轮采用了...引入了延时队列以减少空轮询,将时间轮的推进与任务的提交执行隔离开,提升模型的效率。

    LsCron Java定时任务小工具,适用于指定时间修改状态等场景 软件架构使用DeplayQueue延时队列实现

    该工具使用DeplayQueue延时队列作为软件架构,通过简单的步骤即可完成安装和使用。首先,你需要创建一个实现LsDelayed接口的任务类,并设置任务的名称和执行时间戳。然后,通过CronDelayQueue的init方法初始化任务...

    延时队列我在项目里是怎么实现的?.doc

    标题中的“延时队列”是指一种特殊类型的队列,它的主要特点是消息不会立即被处理,而是会在预定的时间延迟后才被消费。这种技术在很多场景下非常有用,例如在需要定时任务、订单超时处理或者消息缓存等方面。描述中...

    DelayQueue延迟队列和Redis缓存实现订单自动取消功能

    当这个延迟时间到达零时,元素才可从队列中取出。在订单自动取消功能中,我们可以创建一个表示订单的类,实现Delayed接口,并设置一个代表订单超时时间的延迟值。 Redis是一个高性能的键值数据库,常用于缓存和消息...

    Java延迟队列原理与用法实例详解

    Java延迟队列是一种特殊的队列结构,它允许元素在队列中等待一段时间,然后才能被消费。在Java中,延迟队列是通过 DelayQueue 实现的,Delayed 接口定义了延迟队列的元素必须实现的两个方法:compareTo 和 getDelay...

    RabbitMQ死信队列应用1

    当消息在业务队列中处理失败,如因异常导致重试次数达到上限,就会变为死信。DLX允许将这些死信重新发布到另一个特定的Exchange,以便进行后续处理。 1. **死信队列定义** DLX是RabbitMQ中处理异常或无效消息的一...

    rabbitmq_delayed.zip

    在这个名为"rabbitmq_delayed.zip"的压缩包中,我们看到的是一个使用SpringBoot框架实现的RabbitMQ延时队列功能的示例代码。下面将详细解释RabbitMQ延时队列的工作原理以及如何在SpringBoot应用中进行集成。 延时...

    操作系统模拟:多级反馈队列

    4. **定时器和延时**:Java的`Timer`类或`ScheduledExecutorService`可以用来设定线程在特定时间后执行,这对应于进程在队列中的等待时间。 5. **队列数据结构**:为了实现多级队列,可能需要使用Java的`Queue`接口...

    1分钟实现“延迟消息”功能

    使用环形队列实现的延迟消息功能具有以下显著优点: 1. **高效性**:避免了定时任务的轮询机制,减少了不必要的数据库操作。 2. **一次性执行**:确保每个任务仅被执行一次,避免了重复计算。 3. **精确的时效性**...

    如何使用SpringBoot与RabbitMQ结合实现延迟队列

    何为延迟队列?顾名思义,延迟队列就是进入该队列的消息会被延迟消费的队列。而一般的队列,消息一旦...如果不使用延迟队列,那么我们只能通过一个轮询扫描程序去完成。这种方案既不优雅,也不方便做成统一的服务便于

    互联网延迟队列解决方案设计.pdf

    1. 基于编程语言的解决方案:这种方案通常使用编程语言中提供的定时器、延时队列等组件。例如,Java中的Timer和DelayQueue,可以实现简单的延迟任务。但这种方法一般适用于单机场景,因为它难以应对分布式系统中的...

Global site tag (gtag.js) - Google Analytics