Bootstrap

java DelayQueue的使用demo

DelayQueue是什么:

是一个先进先出的队列,里面的元素只有指定的时间到了,才可以被取到。
具体的时间策略由元素来决定.

测试代码:

package com.abc.test;


import com.google.common.base.Stopwatch;
import com.google.common.primitives.Ints;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

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


/**
 * 注意:以下测试用例只能单独执行.
 */
public class DelayQueueTest {

    static class MyDelayedObject implements Delayed {

        public final long startTime;
        private final String uniqueName;

        /**
         * 只有在初始化多少秒之后才可以取到这个对象.
         *
         * @param delayseconds
         */
        public MyDelayedObject(String uniqueName, long delayseconds) {
            this.uniqueName = uniqueName;
            //startTime是现在的时间加上参数值。也就是说参数就是多少秒之后这个元素才可以取到.
            this.startTime = System.currentTimeMillis() + delayseconds * 1000;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            long diff = startTime - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            return Ints.saturatedCast(
                    this.startTime - ((MyDelayedObject) o).startTime);
        }
    }

    DelayQueue<MyDelayedObject> delayQueue = new DelayQueue<>();

    /**
     * 先准备3个元素,供每个测试用例使用.
     */
    @Before
    public void init() {
        delayQueue.add(new MyDelayedObject("2", 2));
        delayQueue.add(new MyDelayedObject("5", 5));
        delayQueue.add(new MyDelayedObject("10", 10));
    }

    /**
     * 直接取数据,不等待,为空.
     */
    @Test
    public void test1NoWait() {
        Assert.assertNull(delayQueue.poll());
    }

    /**
     * take,一直等数据到来.
     */
    @Test
    public void testTake() throws InterruptedException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        //为了使计时更准确,先清空之前的元素。
        delayQueue.clear();
        //再重新加入一个2的元素.2秒之后才可以被取到
        delayQueue.add(new MyDelayedObject("2", 2));
        //这样到take,时间应该在2秒以上。
        Assert.assertNotNull(delayQueue.take());
        long duration = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
        System.out.println(duration + "");
        Assert.assertTrue(duration >= 2000);
    }

    /**
     * 等待3秒再去取数据,可以取到MyDelayedObject(2) .
     */
    @Test
    public void test1Wait3Seconds() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        MyDelayedObject o = delayQueue.poll();
        Assert.assertNotNull(o);
        Assert.assertEquals(o.uniqueName, "2");
    }

    /**
     * 等待7秒再去取数据,取到的仍然是MyDelayedObject(2) .
     */
    @Test
    public void test1Wait7Seconds() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        MyDelayedObject o = delayQueue.poll();
        Assert.assertNotNull(o);
        Assert.assertEquals(o.uniqueName, "2");
        Assert.assertEquals(delayQueue.size(), 2);
    }

    /**
     * 等待7秒再去取数据,取到的仍然是MyDelayedObject(2) .
     */
    @Test
    public void test1Wait7Seconds2() throws InterruptedException {
        TimeUnit.SECONDS.sleep(7);
        delayQueue.poll();
        MyDelayedObject o = delayQueue.poll();
        Assert.assertNotNull(o);
        Assert.assertEquals(o.uniqueName, "5");
        Assert.assertEquals(delayQueue.size(), 1);
    }

    /**
     * 等待12秒再去取数据,
     * 先poll两次.最后的就是 MyDelayedObject(10).
     */
    @Test
    public void test1Wait12Seconds() throws InterruptedException {
        TimeUnit.SECONDS.sleep(12);
        delayQueue.poll();
        delayQueue.poll();
        MyDelayedObject o = delayQueue.poll();
        Assert.assertNotNull(o);
        Assert.assertEquals(o.uniqueName, "10");
        Assert.assertEquals(delayQueue.size(), 0);
    }

    /**
     * size为3。
     * 需要单独运行.
     */
    @Test
    public void testSize() throws InterruptedException {
        Assert.assertEquals(delayQueue.size(), 3);
    }

    /**
     * clear之后size为0。
     * 需要单独运行.
     */
    @Test
    public void testClear() throws InterruptedException {
        delayQueue.clear();
        Assert.assertEquals(delayQueue.size(), 0);
    }

}

欢迎评论区留言

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;