-
Bug
-
Resolution: Fixed
-
P3
-
fx2.0
There is a problem with Toolkit.exit(), and how it clears the fxUserThread field. The problem is that any subsequent call to isFxApplicationThread will return false, since anyThread == null will return false. This can happen quite easily. I have a background thread which does Platform.runLater(). In the body of the runLater(), it checks isFxApplicationThread (because it tries to set some property which performs this check). After closing the window, the background thread and runLater() pump still execute, but the isFxApplicationThread subsequently fails, even though the fx application thread is still processing!
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
/**
*/
public class TaskSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override public void start(Stage primaryStage) throws Exception {
final Button startButton = new Button("Start");
startButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
startButton.setText("Running");
new Thread(new Runnable() {
@Override public void run() {
try {
// Do some seriously complicated stuff :-)
double aperyConstant = 1;
for (int i=2; i<1000000; i++) {
aperyConstant += 1.0 / Math.pow(i, 3);
final int iteration = i;
final double constant = aperyConstant;
Platform.runLater(new Runnable() {
@Override public void run() {
if (!Platform.isFxApplicationThread()) {
System.err.println(Thread.currentThread());
System.err.println("isFxApplicationThread returns false");
} else if (iteration % 1000 == 0) {
System.out.println("Constant is " + constant);
}
}
});
Thread.sleep(1);
}
} catch (InterruptedException ex) {
System.err.println("Interrupted");
}
}
}).start();
}
});
Scene scene = new Scene(startButton);
primaryStage.setScene(scene);
primaryStage.setVisible(true);
}
}
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
/**
*/
public class TaskSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override public void start(Stage primaryStage) throws Exception {
final Button startButton = new Button("Start");
startButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
startButton.setText("Running");
new Thread(new Runnable() {
@Override public void run() {
try {
// Do some seriously complicated stuff :-)
double aperyConstant = 1;
for (int i=2; i<1000000; i++) {
aperyConstant += 1.0 / Math.pow(i, 3);
final int iteration = i;
final double constant = aperyConstant;
Platform.runLater(new Runnable() {
@Override public void run() {
if (!Platform.isFxApplicationThread()) {
System.err.println(Thread.currentThread());
System.err.println("isFxApplicationThread returns false");
} else if (iteration % 1000 == 0) {
System.out.println("Constant is " + constant);
}
}
});
Thread.sleep(1);
}
} catch (InterruptedException ex) {
System.err.println("Interrupted");
}
}
}).start();
}
});
Scene scene = new Scene(startButton);
primaryStage.setScene(scene);
primaryStage.setVisible(true);
}
}
- relates to
-
JDK-8113904 Need Toolkit shutdown hook to clean up resources, etc.
- Closed
-
JDK-8116468 Ensure that Platform.runLater after Toolkit.exit is a no-op on all platforms
- Closed
-
JDK-8128709 PlatformImpl.runAndWait should throw exception if called after the JavaFX runtime has terminated
- Closed