欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中延时队列的使用

程序员文章站 2022-04-08 13:55:01
...

     最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅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);
		}
	}
}

 执行结果:


java中延时队列的使用
            
    
    博客分类: java基础 java基础延时队列delayeddelayqueue 
 

  • java中延时队列的使用
            
    
    博客分类: java基础 java基础延时队列delayeddelayqueue 
  • 大小: 36.9 KB