8338765: ScheduledThreadPoolExecutor struggles with extremely long delays

Reviewed-by: alanb
This commit is contained in:
Viktor Klang 2024-08-27 13:23:02 +00:00
parent d5c6158ced
commit 414d23cb8f

View File

@ -182,6 +182,11 @@ public class ScheduledThreadPoolExecutor
*/
private static final AtomicLong sequencer = new AtomicLong();
/**
* Maximum delay is effectively 146 years
*/
private static final long MAX_NANOS = (Long.MAX_VALUE >>> 1) - 1;
private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {
@ -525,25 +530,7 @@ public class ScheduledThreadPoolExecutor
* Returns the nanoTime-based trigger time of a delayed action.
*/
long triggerTime(long delay) {
return System.nanoTime() +
((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}
/**
* Constrains the values of all delays in the queue to be within
* Long.MAX_VALUE of each other, to avoid overflow in compareTo.
* This may occur if a task is eligible to be dequeued, but has
* not yet been, while some other task is added with a delay of
* Long.MAX_VALUE.
*/
private long overflowFree(long delay) {
Delayed head = (Delayed) super.getQueue().peek();
if (head != null) {
long headDelay = head.getDelay(NANOSECONDS);
if (headDelay < 0 && (delay - headDelay < 0))
delay = Long.MAX_VALUE + headDelay;
}
return delay;
return System.nanoTime() + Math.min(delay, MAX_NANOS);
}
/**