java DelayedQueue延迟队列

代码如下:

package com.example.base.concurrent;

import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import com.example.spring.MyLog;

public class MyDelayedQueue {
    public static void main(String[] args) throws InterruptedException {
        test();
    }
    private static void test() throws InterruptedException {
        DelayQueue<DelayedTask> queue = new DelayQueue<>();
        producer(queue);
        MyLog.info("start take task from queue");
        //循环从队列中取数据
        while(!queue.isEmpty()) {
            //只有到期的数据才能取的出来,否则就阻塞等待
            MyLog.info(queue.take());
        }

    }
    private static void producer(DelayQueue<DelayedTask> queue) {
        for (int i = 0; i < 10; i++) {
            queue.put(new DelayedTask((10 - i) * 1000, "delayed taask"+i));
        }
    }

    public static void info(Object object) {
        System.out.println(new Date() + " [" + Thread.currentThread().getName() + "] " + object);
    }

    private static class DelayedTask implements Delayed {
        private long delay;
        private long expire;
        private String msg;

        public DelayedTask(long delay, String msg) {
            this.delay = delay;
            this.msg = msg;
            this.expire = System.currentTimeMillis() + delay;
        }

        /**
         * 用于延迟队列内部进行排序,将最先到期的放在队首,保证take出来的是到期的那个
         */
        @Override
        public int compareTo(Delayed o) {
            return (int)(this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
        }

        /**
         * 指定到期时间计算规则
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        @Override
        public String toString() {
            return "DelayedTask [delay=" + delay + ", expire=" + expire + ", msg=" + msg + "]";
        }
    }
}

执行结果如下:

2019-07-14T11:57:36.440+08:00 INFO [main] [[email protected]:17] -start take task from queue
2019-07-14T11:57:37.186+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=1000, expire=1563076657181, msg=delayed taask9]
2019-07-14T11:57:38.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=2000, expire=1563076658181, msg=delayed taask8]
2019-07-14T11:57:39.181+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=3000, expire=1563076659181, msg=delayed taask7]
2019-07-14T11:57:40.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=4000, expire=1563076660181, msg=delayed taask6]
2019-07-14T11:57:41.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=5000, expire=1563076661181, msg=delayed taask5]
2019-07-14T11:57:42.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=6000, expire=1563076662181, msg=delayed taask4]
2019-07-14T11:57:43.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=7000, expire=1563076663181, msg=delayed taask3]
2019-07-14T11:57:44.181+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=8000, expire=1563076664181, msg=delayed taask2]
2019-07-14T11:57:45.181+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=9000, expire=1563076665180, msg=delayed taask1]
2019-07-14T11:57:46.182+08:00 INFO [main] [[email protected]:19] -DelayedTask [delay=10000, expire=1563076666180, msg=delayed taask0]

原文地址:https://www.cnblogs.com/gc65/p/11183771.html

时间: 2024-11-12 19:07:25

java DelayedQueue延迟队列的相关文章

java延迟队列

大多数用到定时执行的功能都是用任务调度来做的,单身当碰到类似订餐业务/购物等这种业务就不好处理了,比如购物的订单功能,在你的订单管理中 有N个订单,当订单超过十分钟未支付的时候自动释放购物车中的商品,订单失效.这种高频率的延迟任务再用任务调度(定时)实现就得不偿失了.推荐用Java延迟队列来实现,DelayQueue是java.util.concurrent中提供的一个类DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象, 其中的对象只能在其到期时

java延迟队列DelayQueue使用及原理

概述 java延迟队列提供了在指定时间才能获取队列元素的功能,队列头元素是最接近过期的元素.没有过期元素的话,使用poll()方法会返回null值,超时判定是通过getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0来判断.延时队列不能存放空元素. 延时队列实现了Iterator接口,但iterator()遍历顺序不保证是元素的实际存放顺序. 队列元素 DelayQueue<E extends Delayed>的队列元素需要实现Delayed接口,该接口类定义如下:

灵感来袭,基于Redis的分布式延迟队列

延迟队列 延迟队列,也就是一定时间之后将消息体放入队列,然后消费者才能正常消费.比如1分钟之后发送短信,发送邮件,检测数据状态等. Redisson Delayed Queue 如果你项目中使用了redisson,那么恭喜你,使用延迟队列将非常的简单. 基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的RDelayedQueue Java对象在实现了RQueue接口的基础上提供了向队列按要求延迟添加项目的功能.该功能可以用来实现消息传送延迟按几何增长或几何衰减的发

有赞延迟队列设计

延迟队列,顾名思义它是一种带有延迟功能的消息队列. 那么,是在什么场景下我才需要这样的队列呢? 背景 我们先看看以下业务场景: 当订单一直处于未支付状态时,如何及时的关闭订单,并退还库存? 如何定期检查处于退款状态的订单是否已经退款成功? 新创建店铺,N天内没有上传商品,系统如何知道该信息,并发送激活短信?等等 为了解决以上问题,最简单直接的办法就是定时去扫表.每个业务都要维护一个自己的扫表逻辑. 当业务越来越多时,我们会发现扫表部分的逻辑会非常类似.我们可以考虑将这部分逻辑从具体的业务逻辑里面

RabbitMQ 延迟队列实现订单支付结果异步阶梯性通知

在第三方支付中,例如支付宝.或者微信,对于订单请求,第三方支付系统采用的是消息同步返回.异步通知+主动补偿查询的补偿机制. 由于互联网通信的不可靠性,例如双方网络.服务器.应用等因素的影响,不管是同步返回.异步通知.主动查询报文都可能出现超时无响应.报文丢失等情况,所以像支付业务,对结果的通知一般采用几种方案结合的补偿机制,不能完全依赖某一种机制. 例如一个支付结果的通知,一方面会在支付页面跳转时候返回支付结果(一般只用作前端展示使用,非最终状态),同时会采用后台异步通知机制(有前台.后台通知的

Spring Boot(十四)RabbitMQ延迟队列

一.前言 延迟队列的使用场景:1.未按时支付的订单,30分钟过期之后取消订单:2.给活跃度比较低的用户间隔N天之后推送消息,提高活跃度:3.过1分钟给新注册会员的用户,发送注册邮件等. 实现延迟队列的方式有两种: 通过消息过期后进入死信交换器,再由交换器转发到延迟消费队列,实现延迟功能: 使用rabbitmq-delayed-message-exchange插件实现延迟功能: 注意: 延迟插件rabbitmq-delayed-message-exchange是在RabbitMQ 3.5.7及以上

rabbitmq延迟队列demo

工程结构: 定义jar包依赖的版本,版本很重要,rabbit依赖spring,必须一致,否则报错: <properties> <springframework.version>4.2.7.RELEASE</springframework.version> <spring-rabbit.version>1.6.1.RELEASE</spring-rabbit.version> <junit.version>4.12</junit.

SpringBoot:RabbitMQ 延迟队列

SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程 初探RabbitMQ消息队列中介绍了RabbitMQ的简单用法,顺带提及了下延迟队列的作用.所谓延时消息就是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 延迟队列 延迟队列能做什么? 订单业务: 在电商/点餐

【RabbitMQ】一文带你搞定RabbitMQ延迟队列

本文口味:鱼香肉丝? ?预计阅读:10分钟 一.说明 在上一篇中,介绍了RabbitMQ中的死信队列是什么,何时使用以及如何使用RabbitMQ的死信队列.相信通过上一篇的学习,对于死信队列已经有了更多的了解,这一篇的内容也跟死信队列息息相关,如果你还不了解死信队列,那么建议你先进行上一篇文章的阅读. 这一篇里,我们将继续介绍RabbitMQ的高级特性,通过本篇的学习,你将收获: 什么是延时队列 延时队列使用场景 RabbitMQ中的TTL 如何利用RabbitMQ来实现延时队列 二.本文大纲