Fork me on GitHub

Thread Management

Writing concurrent application could be painful ! Not with JRebirth

Thread Management

Threading overview

JRebirth is multi-threaded, not only by using Task Worker provided by JavaFX APIs. JRebirth has got its own Thread to manage local events (called waves) allowing components to communicate with each others. It also allows to manage multiple threads in a very simple manner with its included thread pool.

Thus all inner JRebirth tasks are processed into a custom thread and don't infer with the JavaFX Application Thread which have to manage user events and some UI instantiation.

Lags, UI Freeze ... are lost to history :D

What happens when you debug a JRebirth application ? You can observe a lot of threads, but don't be scared !! Everything is at the right isolated place doing the right thing.

The most important are :

  • JavaFX Application Thread - JAT
  • JRebirth Internal Thread - JIT
  • JRebirth Slot x (n threads available in JRebirth Thread Pool - JTP Slot 'n')

Other threads are related to JavaFX platform, JRebirth only creates 2 to 5 threads (by default) that can be extended if required.

Concurrent Class Diagram

Thread Rules

JavaFX toolkit requires that all UI tasks must be done into the JAT, but it also allows to build a view into the JIT or JTP and then link it to your scene into the JAT.

All Wave processing tasks are automatically done into the JIT.

When the JRebirth Framework needs to update UI (thanks to Model layer), it's done automatically done into the JAT. No matters to have !

But when you call a component directly (synchronous method: getCommand, getService, getModel ), your call is processed into the current thread, so you must pay attention to what you are doing.

Launch a runnable into JAT

106
116
void callCommand(final Class<? extends Command> commandClass, final WaveData<?>... data);
void callCommand(final Class<? extends Command> commandClass, final WaveBean waveBean);

Launch a runnable into JIT

106
116
void callCommand(final Class<? extends Command> commandClass, final WaveData<?>... data);
void callCommand(final Class<? extends Command> commandClass, final WaveBean waveBean);

Launch a runnable into JTP

106
116
void callCommand(final Class<? extends Command> commandClass, final WaveData<?>... data);
void callCommand(final Class<? extends Command> commandClass, final WaveBean waveBean);

Examples

If you are into the JIT:

  • getCommand => the code will be processed synchronously into the JIT, but if you call the run method of the command it will be run into the thread defined by the command configuration.
  • getModel => all called methods of the model will be processed into the JIT ==> Can Break !!! Toolkit will raise an error.

When you are into the JIT you must use JRebirth.runIntoJAT that call internally Platform.runLater to perform UI updates.

JRebirth Framework offers some default commands to do the trick ( DefaultUiCommand ). Moreover if you send a Wave with a WaveType listened by a model, it will be automatically processed into the JAT (Cool JRebirth Magic).

If you are into the JAT:

  • getCommand, getService => this code will be processed into the JAT : Don't perform long task or you will freeze the application !!!
  • getModel => actions will be done into the JAT ==> OK for short UI actions

When you are in the JAT you must use JRebirth.runIntoJIT that call internally JRebirthThread.runLater to run tasks into the core thread.

JRebirth Framework offers some default commands to force to run into JIT & JTP ( DefaultCommand and DefaultPoolCommand ). You can also send a wave that will trigger a command, or call a service into another thread that JAT.

For example:

If you want to call a service which make an asynchronous call to a remote server. You can use the getService method to initiate the call (By default this call will be managed into JRebirth Thread Pool : JTP), but the return must be managed into the JAT:

  • Either use a wave to send data received from remote server, default service will generate a such wave (automatically processed into the JAT for models that listen it)
  • Either call the model from the JAT and access to service results (the first way way is the best to use)