我有以下简单的DelayQueue简单演示。
class DelayedThing implements Delayed {
private final long waitUntil;
private final String name;
public DelayedThing(String name, long wait) {
this.name = name;
this.waitUntil = System.currentTimeMillis() + wait;
System.out.println("DelayedThing(" + name + " wait=" + wait + " until-" + waitUntil);
}
@Override
public long getDelay(TimeUnit unit) {
System.out.println(name + " getDelay = " + unit.convert(waitUntil - System.currentTimeMillis(), TimeUnit.MILLISECONDS));
return unit.convert(waitUntil - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
long diff = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
System.out.println(name + ".compareTo(" + o + ") = " + diff);
return Long.signum(diff);
}
@Override
public String toString() {
return name;
}
}
public void test() throws InterruptedException {
BlockingQueue<Delayed> queue = new DelayQueue<>();
queue.add(new DelayedThing("one second", 1000));
queue.add(new DelayedThing("two seconds", 2000));
queue.add(new DelayedThing("half second", 500));
for (Delayed d : queue) {
System.out.println(d);
}
}
但打印
half second
two seconds
one second
这显然是错误的。
答案 0 :(得分:5)
错误是一个微妙的错误。我假设iterator
的{{1}}将对每个元素执行一系列DelayQueue
次调用。的错!强>
请参阅iterator() JavaDoc:
返回此队列中所有元素(过期和未过期)的迭代器。
这是非常意外的。
一个正确的解决方案如下:
take
请注意,如果您尝试流式传输队列,也会发生此问题:
while (queue.size() > 0) {
System.out.println(queue.take());
}
由于流媒体将在 queue.stream().forEach((d) -> {
System.out.println(d);
});
提供的iterator
上发生,因此也会产生意外结果。