8357146: ForkJoinPool:schedule(*) does not throw RejectedExecutionException when pool is shutdown

Reviewed-by: alanb
This commit is contained in:
Doug Lea 2025-05-26 22:37:42 +00:00
parent bbceab0725
commit 2c034f57d6
2 changed files with 33 additions and 7 deletions

View File

@ -3452,9 +3452,9 @@ public class ForkJoinPool extends AbstractExecutorService
String name = poolName + "-delayScheduler";
if (workerNamePrefix == null)
asyncCommonPool(); // override common parallelism zero
lockRunState();
long isShutdown = lockRunState() & SHUTDOWN;
try {
if ((ds = delayScheduler) == null) {
if (isShutdown == 0L && (ds = delayScheduler) == null) {
ds = delayScheduler = new DelayScheduler(this, name);
start = true;
}
@ -3462,12 +3462,20 @@ public class ForkJoinPool extends AbstractExecutorService
unlockRunState();
}
if (start) { // start outside of lock
// exceptions on start passed to (external) callers
SharedThreadContainer ctr;
if ((ctr = container) != null)
ctr.start(ds);
else
ds.start();
try {
if ((ctr = container) != null)
ctr.start(ds);
else
ds.start();
} catch (RuntimeException | Error ex) { // back out
lockRunState();
ds = delayScheduler = null;
unlockRunState();
tryTerminate(false, false);
if (ex instanceof Error)
throw ex;
}
}
}
return ds;

View File

@ -644,4 +644,22 @@ public class ForkJoinPool20Test extends JSR166TestCase {
}
}
/**
* schedule throws RejectedExecutionException if shutdown before
* first delayed task is submitted
*/
public void testInitialScheduleAfterShutdown() throws InterruptedException {
Runnable r = new NoOpRunnable();
boolean rje = false;
try (final ForkJoinPool p = new ForkJoinPool(1)) {
p.shutdown();
assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
try {
p.schedule(r, 1, MILLISECONDS);
} catch (RejectedExecutionException ok) {
rje = true;
}
}
assertTrue(rje);
}
}