baler项目总结-DelayQueue队列使用(一)

来源:互联网 发布:vivo手机一键锁屏软件 编辑:程序博客网 时间:2024/06/07 07:09

先看一段定义,
Delayed 元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。

场景

  • 关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之。
  • 缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出。
  • 任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求。

一种笨笨的办法就是,使用一个后台线程,遍历所有对象,挨个检查。这种笨笨的办法简单好用,但是对象数量过多时,可能存在性能问题,检查间隔时间不好设置,间隔时间过大,影响精确度,多小则存在效率问题。而且做不到按超时的时间顺序处理。

代码

需求

将一组数据设置一个倒计时时间,时间一到立刻消费这个数据。

实现

package com.eju.ess;import java.util.Random;import java.util.concurrent.DelayQueue;import java.util.concurrent.Delayed;import java.util.concurrent.Executor;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import org.junit.Test;import lombok.Data;import lombok.extern.slf4j.Slf4j;@Slf4j@Datapublic class DataEntity implements Delayed{    // 数据key    private String dataKey;    // 数据创建时间    private long startTime;    // 延迟多久执行    private long delayTime;    /**     * 排序算法     */    @Override    public int compareTo(Delayed o) {        DataEntity that = (DataEntity) o;        if (this.getTargetTime() < that.getTargetTime())            return -1;        if (this.getTargetTime() > that.getTargetTime())            return 1;        return 0;    }    /**     * 计算目标执行时间和当前时间差     */    @Override    public long getDelay(TimeUnit unit) {        long result=unit.convert(this.getTargetTime() - System.currentTimeMillis(),TimeUnit.MILLISECONDS);        return result;    }    private long getTargetTime(){        return startTime + delayTime;    }    @Test    public void test(){        DelayQueue<DataEntity> delayQueue=new DelayQueue<DataEntity>();        for(int i=0;i<=5;i++){            DataEntity dataEntity=new DataEntity();            dataEntity.setDataKey("数据 "+i);            dataEntity.setStartTime(System.currentTimeMillis());            int randomNum=new Random().nextInt(10);            dataEntity.setDelayTime(randomNum*1000);            log.info("{} 需要延迟 {}",dataEntity.getDataKey(),dataEntity.getDelayTime());            delayQueue.put(dataEntity);        }        log.info("---------------------------------------");        Executor executor=Executors.newCachedThreadPool();        executor.execute(new Runnable() {            @Override            public void run() {                while(true){                    try {                        DataEntity dataEntity=delayQueue.take();                        log.info("{} 开始执行 ",dataEntity.getDataKey());                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        });        try {            TimeUnit.DAYS.sleep(Long.MAX_VALUE);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

参考

1,精巧好用的DelayQueue

==手机QQ扫描下方二维码,快速加入Java架构师交流群==

image

0 0
原创粉丝点击