I've found DelayQueue
, which is exactly what I need. In general, I agree that a ScheduledExecutorService
is better, but I already have an executor and I want full control of the timing.
So I have to implement the Delayed
interface. This forced me to add clock
(an instance of my tiny wrapper around java.time.Clock
), so I get the current time:
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);
}
Now I need to implement Comparable<Delayed>
, i.e., to compare instances of my class to any instance of Delayed
. I guess that
public int compareTo(Delayed that) {
return instant.compareTo(((MyClass) that).instant);
}
would lead to a ClassCastException
somewhere. The other possibility is using
public int compareTo(Delayed that) {
return Long.compare(
this.getDelay(TimeUnit.NANOSECOND),
that.getDelay(TimeUnit.NANOSECOND));
}
But such a method could have been implemented in the interface (there's nothing specific to my class there) or simply omitted as the queue could use a corresponding Comparator
.
Moreover, as getDelay
depends on the current time, it's not possible to implement the method really correctly as some time passes between the invocations. For example, myInstance.compareTo(myInstance)
would return non-zero because of this. This case can be easily countered by testing this==that
first, however I can't see any general solution (apart from some ugly ThreadLocal
hack).
What am I missing?