Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8353155

FutureTask#run(): doc implies synchronous, implementation is async

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      The documentation for FutureTask#run(), and for the RunnableFuture#run() interface method that it implements, says that the run() method "Sets this Future to the result of its computation unless it has been cancelled." This implies that the method is synchronous, i.e. that after calling run(), the Future has been set to the result of the computation, implying that the computation has completed, unless it has been cancelled.

      In the common case where run() is called only once, the implementation is synchronous.
      However, the implementation is not always synchronous.
      When FutureTask#run() is called in one thread and then called again in a second thread,
      the second call returns immediately without waiting for the computation to complete.
      This is inconsistent with the documentation.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the test case code below.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Given the current documentation, I would expect the output to be:

      Task running...
      Calling run() again in main thread.
      Task finished
      Second run() call returned.
      Waiting for result:
      Done

      However, given the large amount of code that might be affected by changing the implementation, it is probably safer to fix the documentation to match the current behaviour rather than changing the implementation to match the current docs.
      ACTUAL -
      The actual output is as follows:

      Task running...
      Calling run() again in main thread.
      Second run() call returned.
      Waiting for result:
      Task finished
      Done

      Note that "Second run() call returned." is output before "Task finished", indicating that the second run() call was not synchronous.

      ---------- BEGIN SOURCE ----------
      cat > MinimalFutureTaskRun.java <<EOF
      import java.util.concurrent.Callable;
      import java.util.concurrent.FutureTask;

      public class MinimalFutureTaskRun {

          public static void main(String[] args) throws Exception {
              Callable<String> task = () -> {
                  System.out.println("Task running...");
                  Thread.sleep(5000); // Simulate a short task
                  System.out.println("Task finished");
                  return "Done";
              };

              FutureTask<String> futureTask = new FutureTask<>(task);

              // First call to run in a new thread
              Thread thread1 = new Thread(futureTask);
              thread1.start();
              Thread.sleep(1000); // Give thread1 a tiny head start

              // Second call to run in the main thread
              System.out.println("Calling run() again in main thread.");
              futureTask.run();
              System.out.println("Second run() call returned.");
              System.out.println("Waiting for result:");
              System.out.println(futureTask.get());
          }
      }
      EOF
      javac MinimalFutureTaskRun.java
      java MinimalFutureTaskRun
      ---------- END SOURCE ----------

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: