DelayQueue阻塞队列第一章:代码示例

DelayQueue阻塞队列系列文章

DelayQueue阻塞队列第一章:代码示例
DelayQueue阻塞队列第二章:源码解析

介绍

在实际的业务中,DelayQueue有很广泛的使用场景,他是java并发包concurrent下的DelayQueue类,主要作用就是进行任务的延时执行

业务场景

  • 订单定时过期
  • 任务定时处理
  • 等一切需要时间间隔执行的任务

缺点

因为是java类,所以当你的服务器重启的时候,你DelayQueue中也就不存在了,保存的任务也会随之消失,个人在这一块的处理方法是在重新启动服务器的时候,重新将需要进行延迟处理的任务加入到队列当中,所以一般需要进行延迟处理的任务我都会设置一个过期时间的字段,一方面在显示上很直观,主要目的其实就是为了在重新启动服务器的时候可以重新计算并将任务加入到队列中来

示例代码

代码是网上就可以找到的代码,一方面通过这个代码配合我的源码解析加深对DelayQueue的理解,具体的实际业务场景可以根据这个模版代码进行改编

DelayedElement类(构建封装实际传入数据的构建类)

该类的作用封装的加入队列任务,实现了接口Delayed,需重写方法getDelay方法和

class DelayedElement implements Delayed {

    private final long delay; //延迟时间
    private final long expire;  //到期时间
    private final String msg;   //实际保存的数据
    private final long now; //创建时间

    public DelayedElement(long delay, String msg) {
        this.delay = delay;
        this.msg = msg;
        expire = System.currentTimeMillis() + delay;    //到期时间 = 当前时间+延迟时间
        now = System.currentTimeMillis();
    }

    /**
     * 获得延迟时间   用过期时间-当前时间
     * @param unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(this.expire-System.currentTimeMillis(),TimeUnit.MILLISECONDS);
    }

    /**
     * 队列中内部比较排序
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) -o.getDelay(TimeUnit.MILLISECONDS));
    }
}
getDelay

该方法的作用是获取剩余到期时间,调用的地方参考DelayQueue源码解析,在该类中的take源码解析中,通过调用getDelay方法来判断是否需要从队列中取出元素

compareTo

该方法主要作用是根据指定的规则对队列中的数据进行排序

DelayQueueTest(延迟队列的业务实现类)
public class DelayQueueTest {

    public static void main(String args[]){
        DelayQueue<DelayedElement> delayQueue=new DelayQueue<DelayedElement>();

        producer(delayQueue);//朝生产队列中添加任务事件

        consumer(delayQueue);//从队列中获取任务并执行

        while (true){
            try {
                TimeUnit.HOURS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    private static void producer(DelayQueue<DelayedElement> delayQueue) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                DelayedElement element = new DelayedElement(1000,"test");
                delayQueue.offer(element);
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        TimeUnit.MILLISECONDS.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("delayQueue size:"+delayQueue.size());
                }
            }
        }).start();
    }

    /**
     * 消费者,从延迟队列中获得数据,进行处理
     * @param delayQueue
     */
    private static void consumer(DelayQueue<DelayedElement> delayQueue) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    DelayedElement element = null;
                    try {
                        element =  delayQueue.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(System.currentTimeMillis()+"---"+element);
                }
            }
        }).start();
    }

}

该类使用了生产-消费者模式,所以代码的实现分为元素入队列和取出队列元素
入队操作就是将构建的DelayedElement加入到队列中去,然后在消费方法中取出元素

DelayQueue的使用方法较为简单,只是需要注意的是如果重启服务那么之前保存的任务将会消失,所以需要在项目启动的时候重新将任务加载进队列中来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值