简单的延时消费队列

1. 简单的延时消费队列单元测试,将2个任务添加到队列中,然后消费,代码如下:

package com.robinboot.facade;

import com.robinboot.service.task.DelayRunnable;
import com.robinboot.service.task.DelayRunnable;
import com.robinboot.service.task.TaskManager;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @auther: TF12778
 * @date: 2020/11/26 11:22
 * @description:简单的延时消费队列单元测试,将2个任务添加到队列中,然后消费
 */
public class TaskTest extends BaseTest{

    public static final Logger logger=Logger.getLogger(TaskTest.class);

    ExecutorService singlePooling = Executors.newSingleThreadExecutor();
    DelayRunnable delayTask = new DelayRunnable();

    @Before
    public void tastttt1() {
        singlePooling.submit(delayTask);
    }

    @Test
    public void tastttt() {

        delayTask.put(new Runnable() {
            @Override
            public void run() {
                System.out.println("delayTask------1");
            }
        }, 1);

        delayTask.put(new Runnable() {
            @Override
            public void run() {
                System.out.println("delayTask------2");
            }
        }, 5);
    }
}

执行结果:

 二. DelayRunnable 主要作用:

声明了一个延时任务队列,将任务添加到任务队列中,每100ms取出一个任务去执行, 任务提交到线程池

package com.robinboot.service.task;

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

import java.util.concurrent.*;

/**
 * @auther: TF12778
 * @date: 2020/11/26 11:02
 * @description:声明了一个延时任务队列,将任务添加到任务队列中,每100ms取出一个任务去执行, 任务提交到线程池
 */
public class DelayRunnable implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(DelayRunnable.class);

    private ExecutorService pooling  = new ThreadPoolExecutor(2, 3, 100, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10));

    private DelayQueue<DelayedTask<Runnable>> dQueue = new DelayQueue<>();
    private volatile boolean started = true;

    public void put(Runnable r, long delay){
        dQueue.add(new DelayedTask<Runnable>(r, delay));
    }

    @Override
    public void run() {
        DelayedTask<Runnable> task = null;
        while (started){
            try {
                task = dQueue.poll(100, TimeUnit.MILLISECONDS); // 每100ms取出一个任务去执行
            }catch (InterruptedException e){
                logger.warn("dQueue thread is interrupted.",e);
            }
            if(task != null){
                logger.info("tasks in delayQueue: " + dQueue.size());
                fireTask(task.getItem());
                task = null;
            }
        }
    }

    public void stop(){
        started = false;
    }


    private void fireTask(Runnable r){
        this.pooling.submit(r);  // 任务提交到线程池
    }
}

 

package com.robinboot.service.task;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @auther: sww
 * @date: 2020/11/26 10:57
 * @description:
 */
public class DelayedTask<T> implements Delayed {

    /**
     * Sequence number to break scheduling ties, and in turn to guarantee FIFO order among tied
     * entries.
     */
    private static final AtomicLong SEQUENCER = new AtomicLong(0);
    /** The time the task is enabled to execute in nanoTime units */
    private long time;
    /** Sequence number to break ties FIFO */
    private final long SEQUENCE_NUMBER;
    /** Base of nanosecond timings, to avoid wrapping */
    private static final long NANO_ORIGIN = System.nanoTime();
    private final T item;

    public DelayedTask(T submit, long timeout) {
        this.time = now() + TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
        this.item = submit;
        this.SEQUENCE_NUMBER = SEQUENCER.getAndIncrement();
    }

    public T getItem() {
        return this.item;
    }

    final static long now() {
        return System.nanoTime() - NANO_ORIGIN;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(time - now(), TimeUnit.NANOSECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        if(o == this){
            return 0;
        }
        if(o instanceof DelayedTask){
            DelayedTask t = (DelayedTask) o;
            long diff = this.time - t.time;
            if(diff < 0){
                return -1;
            }else if(diff > 0){
                return 1;
            }else if(SEQUENCE_NUMBER < t.SEQUENCE_NUMBER){
                return -1;
            }else {
                return 1;
            }
        }
        long d = (getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS));
        return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
    }

    @Override
    public boolean equals(Object object){
        if(object ==null || !(object instanceof DelayedTask)){
            return false;
        }
        return this.getItem().equals(((DelayedTask<T>)object).getItem());
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值