我找到了DelayQueue
,这正是我所需要的。一般来说,我同意a ScheduledExecutorService
is better,但我已经有了执行人,我想要完全控制时间。
所以我必须实现Delayed
接口。这迫使我添加clock
(我java.time.Clock
周围的一个小包装的实例),所以我得到了当前的时间:
private final Instant expires;
private final Clock clock; // UGLY!!!
public long getDelay(TimeUnit timeUnit) {
return timeUnit.convert(
Duration.between(expires, clock.now()).toNanos(),
TimeUnit.NANOSECONDS);
}
现在我需要实现Comparable<Delayed>
,即将我的类的实例与 Delayed
的任何实例进行比较。我想那个
public int compareTo(Delayed that) {
return instant.compareTo(((MyClass) that).instant);
}
会在某处导致ClassCastException
。另一种可能是使用
public int compareTo(Delayed that) {
return Long.compare(
this.getDelay(TimeUnit.NANOSECOND),
that.getDelay(TimeUnit.NANOSECOND));
}
但是这样的方法可以在接口中实现(那里没有特定于我的类)或者只是省略,因为队列可以使用相应的Comparator
。
此外,由于getDelay
取决于当前时间,因此在调用之间经过一段时间后,无法真正正确地实现该方法。例如,myInstance.compareTo(myInstance)
因此而返回非零值。通过首先测试this==that
可以很容易地解决这种情况,但是我看不到任何一般的解决方案(除了一些丑陋的ThreadLocal
黑客)。
我错过了什么?