How to run two JavaFX UI in actual different threads


Question

We know, we can run javafx UI updates in a new thread with support of the javaFX Application thread.

  new Thread(new Runnable() {
            @Override
            public void run() {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                       //UI Stuff
                    }
                });
            }
        }).start();

When we start two UI updates , lets think two stages processing in two different threads.

new Thread(...... updateUI(stage1)

new Thread(...... updateUI(stage2)

updateUI method will be something like this.

void updateUI(Stage stage) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                //UI Stuff
            }
        });
    }

The problem is the two stages never update simultaneously. I think they both are using the same javafx Application thread in Platform.runLater.

I want to Update these two stages at the same time. How do I do that (We know can run several UI threads in AWT and swing, any chance with JavaFX)?

1
0
3/14/2017 1:33:16 PM

Accepted Answer

You can't control the threading system for JavaFX, it's single threaded from an application point of view.

The JavaFX application thread is created by the JavaFX system. Read about how this works in the JavaFX architecture overview. Further background information is in the answer to: Javafx: Difference between javafx.concurent and Platform.runLater? and Multithreaded toolkits: A failed dream?

Comments on additional points in your question

When you say "we can run javafx UI updates in a new thread", that is not really true, because you are invoking Platform.runLater which shifts the work on to the JavaFX application thread, so you aren't really running updates in a new thread. You also state that when you call Platform.runLater from multiple threads "The problem is the two stages never update simultaneously" - which is exactly what the documentation for Platform.runLater says it will do "Run the specified Runnable on the JavaFX Application Thread at some unspecified time in the future" - so there are no sequencing guarantees when you utilize Platform.runLater.

I want to Update these two stages at the same time

Rather than creating your own threads, update the scene graphs for both stages in code executing sequentially on the JavaFX application thread (e.g. in the start method or an event handler for your application). Once your application is executing instructions on the JavaFX application thread, all application instructions will be executed before the next "pulse" of the JavaFX thread which renders the modified scene graph - so from a user point of view the two stages will update simultaneously as the pulse renders them. By default, JavaFX will issue rendering pulses sixty times a second. If you do a lot of work on the JavaFX application thread, then there will be a pause before the next pulse occurs (which is why it is advised that you get all of the work done in less than a sixtieth of a second).

If you have to do a lot of work (e.g. some I/O or incredibly computationally expensive task which will take a quarter of a second or more), you will need to make use of the JavaFX concurrency tools referenced earlier to ensure you aren't freezing your UI, then only update the UI once all concurrent tasks have completed - various techniques of which demonstrated in the answer to: How to reset progress indicator between tasks in JavaFX2?

2
5/23/2017 12:09:28 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon