I have multiple worker threads, and a JavaFX GUI which is reporting on what is happening in these threads.
There is a lot of data shared between threads and it needs
The original links with the full example and the example solution by jewelsea are dead, so I'll add an answer with a short summary of what I ended up doing.
To make this easy, let's assume you start with 1 class that holds your data model (let's call it DataModel
). An instance of this class is used by multiple threads that change it.
Now the problem is that you want to use the data model in javaFX, but you cannot simply change your data model to use Property
and ObservableList
etc. If you do that, the listeners will be called from non-javafx threads, and GUI's bound to them will throw exceptions.
Instead you need to make a seperate data model class for javaFX. This is simply the JavaFX version of the original one (let's call it FXDataModel
). So this version contains the same info, but it uses javaFX Property
and ObservableList
. This way, you can bind your GUI to it.
The next step is to periodically update a FXDataModel
instance using the DataModel
instance.
To do this, you add an update(DataModel dataModel)
method to FXDataModel
, which copies the data from the original data model into the FXDataModel
instance. This update function must always be called on the javaFX thread. Finally, all you need to do is periodically call that update function.
In my real scenario, I call the update function every 200 ms, and that is more than enough to be able to show a live view of the data model in the GUI. (Things get more complex if you want to more than a view of the data model, and you want to change things from the GUI, but that is not something I needed to do)
Background Info
Task javadoc includes numerous concurrency usage patterns for passing data between threads in JavaFX.
Task includes convenience data transfer methods such as updateMessage and can be used instead of your Runnable with the user defined status property.
When appropriate, consider using a collection structure designed for concurrency, such as a BlockingQueue. An additional advantage is that BlockingQueues can have size limits, which seems like something you want.
Some general advice
The above are just rules of thumb and don't need to be followed didactically.
Reasonably Complex Threading Samples