Docs for ExecutorService#close and canceled tasks

Fabian Meumertzheim fabian at buildbuddy.io
Sun Jan 5 10:20:06 UTC 2025


Hi,

I recently traced a race in an application
(https://github.com/bazelbuild/bazel/issues/21773) down to a
particular behavior of ExecutorService#close that, to me, doesn't seem
to be obvious from its documentation: If a task that has been
submitted to the executor is canceled while it is already executing,
ExecutorService#close will not wait for the associated Runnable to
return.

Consider the following example:

var taskRunning = new AtomicBoolean(true);
try (var executorService = Executors.newVirtualThreadPerTaskExecutor()) {
  var taskStarted = new CountDownLatch(1);
  var task =
      executorService.submit(
          () -> {
            // Uninterruptibly wait for a second.
            taskStarted.countDown();
            long end = System.currentTimeMillis() + 1000;
            long remaining;
            while ((remaining = end - System.currentTimeMillis()) > 0) {
              try {
                Thread.sleep(remaining);
              } catch (InterruptedException e) {
              }
            }
            taskRunning.set(false);
          });
  // Cancel the task after it has started execution.
  try {
    taskStarted.await();
  } catch (InterruptedException e) {
    throw new IllegalStateException(e);
  }
  task.cancel(false);
}
System.err.println("Task still running: " + taskRunning.get());

This will print "Task still running: true" and exit immediately
instead of waiting for a second.

It would have been helpful to me if the phrase "completed execution"
in the docs for #awaitTermination and #close had mentioned that
canceled tasks are always considered to have completed execution, even
if their Runnable hasn't returned yet.

Would a change that more clearly documents this behavior be welcome?
Is there a clear definition of "completed execution" in some other
parts of the j.u.c docs that specifies this behavior?

Fabian


More information about the core-libs-dev mailing list