-
Bug
-
Resolution: Fixed
-
P3
-
None
-
None
ScheduledThreadPoolExecutor provides setExecuteExistingDelayedTasksAfterShutdownPolicy() to specify that "delayed tasks" should be cancelled at shutdown. But if this is set, then non-scheduled tasks (e.g. via submit) or delayed tasks whose delay has expired and which also happen to still be in the queue due to execution backlog, are also cancelled, which seems wrong.
---
import java.util.concurrent.*;
public class STPEShutdownDelayedTasks {
public static void main(String[] args) throws Throwable {
ScheduledThreadPoolExecutor pool
= new ScheduledThreadPoolExecutor(1);
pool.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
CountDownLatch running = new CountDownLatch(1);
CountDownLatch proceed = new CountDownLatch(1);
Runnable task = () -> {
try {
running.countDown();
proceed.await();
} catch (InterruptedException t) { throw new Error(t); }
};
java.util.List<Future<?>> futures = java.util.List.of(
pool.submit(task),
pool.submit(task));
running.await();
pool.shutdown();
proceed.countDown();
if (!pool.awaitTermination(10, TimeUnit.SECONDS))
throw new Error("timed out");
for (Future<?> future : futures) {
System.err.printf("isDone=%s isCancelled=%s%n",
future.isDone(),
future.isCancelled());
}
}
}
=>
isDone=true isCancelled=false
isDone=true isCancelled=true
Neither task should be cancelled at shutdown.
---
import java.util.concurrent.*;
public class STPEShutdownDelayedTasks {
public static void main(String[] args) throws Throwable {
ScheduledThreadPoolExecutor pool
= new ScheduledThreadPoolExecutor(1);
pool.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
CountDownLatch running = new CountDownLatch(1);
CountDownLatch proceed = new CountDownLatch(1);
Runnable task = () -> {
try {
running.countDown();
proceed.await();
} catch (InterruptedException t) { throw new Error(t); }
};
java.util.List<Future<?>> futures = java.util.List.of(
pool.submit(task),
pool.submit(task));
running.await();
pool.shutdown();
proceed.countDown();
if (!pool.awaitTermination(10, TimeUnit.SECONDS))
throw new Error("timed out");
for (Future<?> future : futures) {
System.err.printf("isDone=%s isCancelled=%s%n",
future.isDone(),
future.isCancelled());
}
}
}
=>
isDone=true isCancelled=false
isDone=true isCancelled=true
Neither task should be cancelled at shutdown.