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);
}
}
欢迎评论区留言