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

Mixing the Task and Callable APIs leads to unexpected behavior

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :


      A DESCRIPTION OF THE PROBLEM :
      If you extend a Task class, and also mark it as implementing the Callable interface, then submit the task to an ExecutorCompletionService, the task perform any of the actions that a task is supposed to do. Calling get() on the task will result in an indefinite block, because the task state never transitions, even though the task is executed.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.ExecutorCompletionService;
      import java.util.concurrent.Executors;
      import javafx.concurrent.Task;
      import javafx.embed.swing.JFXPanel;

      public class RunTest
      {
      public static void main(String[] args) throws InterruptedException, ExecutionException
      {
      new JFXPanel(); //start javafx / task API code (why oh why does the Task API require JavaFX to be up?)
      ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(Executors.newSingleThreadExecutor());

      TaskWorks tw = new TaskWorks();
      ecs.submit(tw, null);

      System.out.println("Wait for works");
      tw.get();
      System.out.println("Done");

      TaskFails tf = new TaskFails();
      ecs.submit(tf, null);

      System.out.println("Wait for fails - submitted as runnable");
      tf.get();
      System.out.println("Done");

      tf = new TaskFails();
      ecs.submit(tf);

      System.out.println("Wait for fails - submitted as callable - should block 2 seconds");
      tf.get();
      System.out.println("Done - you won't see this");

      }

      private static class TaskWorks extends Task<Void>
      {
      /**
      * @see javafx.concurrent.Task#call()
      */
      @Override
      public Void call() throws Exception
      {
      updateProgress(1, 2);
      Thread.sleep(2000);
      updateProgress(2, 2);
      return null;
      }
      }

      private static class TaskFails extends Task<Void> implements Callable<Void>
      {
      /**
      * @see javafx.concurrent.Task#call()
      */
      @Override
      public Void call() throws Exception
      {
      updateProgress(1, 2);
      Thread.sleep(2000);
      updateProgress(2, 2);
      return null;
      }
      }

      }
      ---------- END SOURCE ----------

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated: