延时队列的使用

简介: 队列中的数据如何才能更好的去使用,一直存在困惑。使用场景也有些模糊,还在摸索中。有问题就留言吧,一起学习

1、创建延时队列的内容对象
每条需要处理的内容都要单独创建一个,然后再放到队列中

public class DelayedTask<T> implements Delayed {
    //延时时间,毫秒
    private long delay;
    private long expire;
    //需要处理的数据
    private T content;

    public DelayedTask(long delay, T content) {
        this.delay = delay;
        this.content = content;
        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 + ", Content=" + content + "]";
    }
}

2、测试

2.1、无限循环调用

public static void main(String[] args) throws InterruptedException {
        //1、创建队列
        DelayQueue<DelayedTask> queue = new DelayQueue<>();
        //2、插入数据
        for (int i = 1; i <= 3; i++) {
            int ti = 2000;//i==1 ? 20000 :(i==2?4000:8000);
            queue.put(new DelayedTask(ti, "first"));
        }
        System.out.println("start take task from queue" + DateUtil.now());
        //3、循环从队列中取数据
        while (!queue.isEmpty()) {
            //只有到期的数据才能取的出来,否则就阻塞等待
            DelayedTask ddddd = queue.take();
            System.out.println(ddddd);

        }
    }

2.2、线程池调用

import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.cnki.common.readfile.apitype.ProjectAnalysis;
import net.cnki.common.readfile.apitype.ProjectChildAnalysis;
import net.cnki.common.readfile.apitype.ResultAnalysis;
import net.cnki.common.readfile.apitype.SingleFileHandWorkAnalysis;
import net.cnki.common.readfile.apitype.SingleFileUploadsAnalysis;
import net.cnki.common.readfile.apitype.SingleFileZipAnalysis;


/**
 * 基于内存的队列的介绍,基于内存的队列,队列的大小依赖于JVM内存的大小,一般如果是内存占用不大且处理
 * 相对较为及时的都可以采用此种方法。如果你在队列处理的时候需要有失败重试机制,那么用此种队列就不是特别合适了。
 * @author ZhiPengyu
 *
 */
public class QueuePool {
    Logger logger = LoggerFactory.getLogger(QueuePool.class);

    private DelayQueue<DelayedTask> queue = new DelayQueue<>();
    private ScheduledExecutorService es = Executors.newScheduledThreadPool(5);
    
    
    /**
     * 构造执行
     */
    public QueuePool() {}
    /**
     * 添加信息至队列中
     * @param content
     */ 
    public void addQueue(String[] content) { 
        queue.offer(content); 
        execute();
    }
    /**
     * 初始化执行
     */ 
    public void execute() { 
        es.scheduleWithFixedDelay(new Runnable(){ 
            public void run() { 
                try { 
                    
                    DelayedTask ddddd = queue.take();
                    
                } catch (Exception e) { 
                    logger.error(e.toString());
                } 
            }    
        }, 100, 500, TimeUnit.MILLISECONDS); //表示延迟10毫秒后每500毫秒执行一次 。执行一次内,处理队列内容不限,执行一次后隔第二个时间参数后继续执行,一直到队列无内容 
    }//DAYS 天,HOURS 小时,MINUTES 分钟,SECONDS 秒,MILLISECONDS 毫秒
}
public static void main(String[] args) {
        QueuePool pool= new QueuePool();
        pool.addQueue(...);
    }
相关文章
|
消息中间件
RabbitMQ的死信队列和延时队列
RabbitMQ的死信队列和延时队列
|
1月前
|
消息中间件 存储 Java
RabbitMQ之延迟队列(手把手教你学习延迟队列)
【1月更文挑战第12天】延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列的。
535 2
|
1月前
|
消息中间件 数据库
七、延时队列
七、延时队列
52 0
|
11月前
|
消息中间件
死信队列和延迟队列的介绍
死信队列和延迟队列的介绍
|
11月前
|
消息中间件
RabbitMQ 的死信队列、延迟队列
RabbitMQ 的死信队列、延迟队列
76 0
|
11月前
|
消息中间件 存储 NoSQL
RibbitMQ学习笔记延迟队列(二)
RibbitMQ学习笔记延迟队列
67 0
|
11月前
|
消息中间件 Java 数据库
RibbitMQ学习笔记延迟队列(一)
RibbitMQ学习笔记延迟队列
45 0
|
消息中间件 Java Kafka
15、RabbitMQ没有延时队列?学会这一招玩转延时队列
15、RabbitMQ没有延时队列?学会这一招玩转延时队列
219 0
15、RabbitMQ没有延时队列?学会这一招玩转延时队列
|
消息中间件 Java Kafka
RabbitMQ没有延时队列?我就教你一招,玩转延时队列
延时队列:顾名思义,是一个用于做消息延时消费的队列。但是它也是一个普通队列,所以它具备普通队列的特性,相比之下,延时的特性就是它最大的特点。所谓的延时就是将我们需要的消息,延迟多久之后被消费。普通队列是即时消费的,延时队列是根据延时时间,多久之后才能消费的。
|
消息中间件 JSON 数据库
rabbitMQ延时队列与TTL和DLX、延迟队列的相关介绍
TTL是Time To Live的缩写, 也就是生存时间。 RabbitMq支持对消息和队列设置TTL,对消息这设置是在发送的时候指定,对队列设置是从消息入队列开始计算, 只要超过了队列的超时时间配置, 那么消息会自动清除。 如果两种方式一起使用消息的TTL和队列的TTL之间较小的为准,也就是消息5s过期,队列是10s,那么5s的生效。 默认是没有过期时间的,表示消息没有过期时间;如果设置为0,表示消息在投递到消费者的时候直接被消费,否则丢弃。