On Sun, 23 Feb 2025 15:26:48 GMT, Doug Lea <[email protected]> wrote:
>> (Copied from https://bugs.openjdk.org/browse/JDK-8319447)
>>
>> The problems addressed by this CR/PR are that ScheduledThreadPoolExecutor is
>> both ill-suited for many (if not most) of its applications, and is a
>> performance bottleneck (as seen especially in Loom and CompletableFuture
>> usages). After considering many options over the years, the approach taken
>> here is to connect (lazily, only if used) a form of ScheduledExecutorService
>> (DelayScheduler) to any ForkJoinPool (including the commonPool), which can
>> then use more efficient and scalable techniques to request and trigger
>> delayed actions, periodic actions, and cancellations, as well as coordinate
>> shutdown and termination mechanics (see the internal documentation in
>> DelayScheduler.java for algotihmic details). This speeds up some Loom
>> operations by almost an order of magnitude (and similarly for
>> CompletableFuture). Further incremental improvements may be possible, but
>> delay scheduling overhead is now unlikely to be a common performance concern.
>>
>> We also introduce method submitWithTimeout to schedule a timeout that
>> cancels or otherwise completes a submitted task that takes too long. Support
>> for this very common usage was missing from the ScheduledExecutorService
>> API, and workarounds that users have tried are wasteful, often leaky, and
>> error-prone. This cannot be added to the ScheduledExecutorService interface
>> because it relies on ForkJoinTask methods (such as completeExceptionally) to
>> be available in user-supplied timeout actions. The need to allow a pluggable
>> handler reflects experience with the similar CompletableFuture.orTimeout,
>> which users have found not to be flexible enough, so might be subject of
>> future improvements.
>>
>> A DelayScheduler is optionally (on first use of a scheduling method)
>> constructed and started as part of a ForkJoinPool, not any other kind of
>> ExecutorService. It doesn't make sense to do so with the other j.u.c pool
>> implementation ThreadPoolExecutor. ScheduledThreadPoolExecutor already
>> extends it in incompatible ways (which is why we can't just improve or
>> replace STPE internals). However, as discussed in internal documentation,
>> the implementation isolates calls and callbacks in a way that could be
>> extracted out into (package-private) interfaces if another j.u.c pool type
>> is introduced.
>>
>> Only one of the policy controls in ScheduledThreadPoolExecutor applies to
>> ForkJoinPools with DelaySchedulers: new method cancelDelayedTasksOnShutdown
>> controls whether quiescent shutdown sh...
>
> Doug Lea has updated the pull request incrementally with one additional
> commit since the last revision:
>
> Standardize parameter checking
test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java line 510:
> 508:
> 509: try (PoolCleaner cleaner = cleaner(p, done)) {
> 510: for (int i = p.getParallelism(); i--> 0; ) {
Suggestion:
for (int i = p.getParallelism(); i-- > 0; ) {
test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java line 523:
> 521: done.countDown(); // release blocking tasks
> 522: assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
> 523:
Suggestion:
test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java line 577:
> 575: Thread.sleep(LONGER_DELAY_MS); return Boolean.TRUE; }};
> 576: ForkJoinTask<?> task = p.submitWithTimeout(c, 1, NANOSECONDS,
> null);
> 577: Thread.sleep(timeoutMillis());
Do we need to sleep here or just get the result with a timeout expecting a
CancellationException then asserting isCancelled == true?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/23702#discussion_r1970199274
PR Review Comment: https://git.openjdk.org/jdk/pull/23702#discussion_r1970199879
PR Review Comment: https://git.openjdk.org/jdk/pull/23702#discussion_r1970203366