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

Independent Services block each other

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: fx2.1
    • Fix Version/s: 8
    • Component/s: javafx
    • Labels:
    • Environment:

      JavaFX 2.1

      Description

      Run the example below. It creates three services, two long running ones, and one short running one. They are all started at the same time (the short running one started last).

      The result is that the 2 long running services run concurrently, and the short running service waits for the two long running ones to finish before even starting. The short running service should have completed almost immediately, but instead is forced to wait because two other (completely unrelated) services are running.

      The JavaDocs says that the service will create a new daemon thread (note it says thread, not runnable, or callable...) which is then submitted to some executor (which donot accept threads, contradiction...). Clearly however it doesn't create a thread, it just creates a runnable/callable which is then submitted to some internal executor with a thread limit of, apparently, two.

      This is a bit unexpected, and may need to be documented.

      My use-case: I have something that for some reason triggers the downloading of 3 images (2 large ones, and 1 small one). Each uses its own image download Service for this. I was very surprised to see that the small image took so long to download, but apparently it was blocked by the two other Services downloading the large images.


      package hs.mediasystem;

      import javafx.application.Application;
      import javafx.concurrent.Service;
      import javafx.concurrent.Task;
      import javafx.stage.Stage;

      public class ServiceTest extends Application {

        public static void main(String[] args) {
          launch(args);
        }

        @Override
        public void start(Stage primaryStage) throws Exception {

          Service serviceA = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
              return new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                  Thread.sleep(5000);
                  System.out.println("Service A completed");
                  return null;
                }
              };
            }
          };

          Service serviceB = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
              return new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                  Thread.sleep(5000);
                  System.out.println("Service B completed");
                  return null;
                }
              };
            }
          };

          Service serviceC = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
              return new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                  Thread.sleep(500);
                  System.out.println("Service C completed");
                  return null;
                }
              };
            }
          };

          serviceA.start();
          serviceB.start();
          serviceC.start();
        }
      }

        Attachments

          Activity

            People

            • Assignee:
              rbair Richard Bair
              Reporter:
              jhendrikx John Hendrikx
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported: