Thought experiment: constructing Nodes on a different thread...

Nir Lisker nlisker at gmail.com
Thu Jan 25 13:07:44 UTC 2024


Isn't that exactly what the Worker interface and its Task and Service
implementations are for? Service says

A Service is a non-visual component encapsulating the information required
> to perform some work on one or more background threads. As part of the
> JavaFX UI library, the Service knows about the JavaFX Application thread
> and is designed to relieve the application developer from the burden of
> managing multithreaded code that interacts with the user interface.


The example provided by Jurgen uses Task, which guarantees that the
resulting Parent can be attached to the scenegraph on the FX thread (in
'succeeded()'). Up to here everything is fine. The problem starts when the
code from inside Task#call, which is called on the background thread,
starts an animation itself, an operation that interacts with the FX thread.
Task warns about this:

Because the Task is designed for use with JavaFX GUI applications, it
> ensures that every change to its public properties, as well as change
> notifications for state, errors, and for event handlers, all occur on the
> main JavaFX application thread. Accessing these properties from a
> background thread (including the call() method) will result in runtime
> exceptions being raised.


and

Generally, Tasks should not interact directly with the UI. Doing so creates
> a tight coupling between a specific Task implementation and a specific part
> of your UI. However, when you do want to create such a coupling, you must
> ensure that you use Platform.runLater so that any modifications of the
> scene graph occur on the FX Application Thread.


So I don't think you're missing something in your description of the
problem, and I don't think anyone has argued that doing what you described
is not a problem. Thankfully, I don't remember coming across code that does
this. People seem to be vigilant about using javafx.concurrent tools for
this purpose, which is a good sign.

On Thu, Jan 25, 2024 at 11:50 AM John Hendrikx <john.hendrikx at gmail.com>
wrote:

> All this threading talk has made me wonder something:
>
> Let's say there are two threads, the FX thread and Thread 1.  I do the
> following:
>
> - On thread 1: create Label
> - On thread 1: set Label text to "xyz"
>
> I now attach this label to an active Scene graph. This should be done on
> the FX thread as we're going to be manipulating an active Scene graph, so:
>
> - On FX thread: attach Label to active scene graph
>
> There is no synchronization in place on the Label's text field. What
> guarantees do I have that when the label is shown on screen it will show
> "xyz" ?
>
> IMHO, there is no such guarantee, and so any creation or manipulation of
> Nodes that will later be part of an active scene graph (and thus
> accessed by the FX thread) **must** be done on the FX thread.  Involving
> any other thread in their creation or manipulation runs the risk of
> seeing an object in the incorrect state (or even an "impossible" state
> when multiple fields are involved that normally change together).
>
> Effectively, assuming that when you create Nodes you always have the
> intention of showing them at some point, you can never construct Nodes
> on any other thread than the FX thread...
>
> Am I missing something?
>
> --John
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20240125/5d837d3c/attachment-0001.htm>


More information about the openjfx-dev mailing list