I've written a simple JavaFX application that is obviously running on FX application thread. The application needs some background processing in an infinite loop running on a separate thread(not FX thread) where I call Platform.runLater() to update the gui controls of the FX application after a fixed interval. If I close the FX Gui Application, the background thread continues it execution.
In order to terminate the background thread after FX thread has terminated, I am now using fxThread.isAlive() in the while loop on the background thread. This way, the background thread automatically terminates as soon as the FX Thread is terminated as the while loop condition becomes false.
Is this a bad choice? What are the alternative and efficient ways to accomplish the same task?
//imports
public class SimpleClockFX implements Application{
Thread fxThread;
//other variables
@Override
public void start(Stage primaryStage){
fxThread = Thread.currentThread();
//other stuff...
new Thread(()->{
//logic...
while(fxThread.isAlive()){
//logic...
Platform.runLater(()->{
//update gui controls
});
}
}).start();
}
By calling the fxThread.isAlive()
its not quite the best solution , cause in the worst scenario , your fxThread
might die, while the thread has passed the fxThread.isAlive()
and in the time entering the Platform.runLater
will give you an exception , except if this is the proper termination for your case
try adding a listener for the close event on the top level stage.
Also call System.exit(0) to terminate completely the JVM or whatever custom termination methods you want(f.e. explicitly cause interrupt to the background thread if its still running).
@Override
public void start(Stage primaryStage)
{
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
System.out.println("Stage is closing");
System.exit(0);
}
});
primaryStage.setTitle("Hello World!");
// add your components
primaryStage.show();
// not daemon
new Thread(new CustomRunnable()).start();
}
private static class CustomRunnable implements Runnable
{
public void run()
{
while(true){
// long operation
}
}
}
EDIT :
As per @lostsoul29 comments , the scenario implies that the spawning threads are not going to be daemon threads. In case that any thread is marked as daemon , it will require custom termination / handling.