In this example, there is an instance of the Input class and the Result class. The introductory instance is populated in the GUI-Thread, here is the JavaFX Application Thread. After clicking the button, this input instance is used in the workflow. The workflow then instantiates the Result class and populates it with some values after this Platform.runLater is called to update the GUI.
My first question is:
Is it guaranteed that the worker thread sees the values of the Input instance?
I would say yes because of the following: JLS 17.4.5. It happens before the order, says: The start () call in the thread is called - before any actions in the running thread.
So, from my point of view, everything that was done at the beginning of JavaFX Thread before is called. will be visible to the workflow.
My second question:
Is it guaranteed that the JavaFX Application Thread sees the values of the result instance?
I think so, but I'm not sure. Will Platform.runLater guarantee this? How?
package javafxconcurrency;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class JavaFxConcurrency extends Application {
private Input input;
@Override
public void start(Stage primaryStage) {
input = new Input();
input.setId(1);
input.setName("Jack");
Button btn = new Button();
btn.setText("Start a thread");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
Task<Result> task = new Task() {
@Override
protected Object call() throws Exception {
final Result result = queryDB(input);
Platform.runLater(new Runnable() {
@Override
public void run() {
updateGUI(result);
}
});
return result;
}
private Result queryDB(Input input) {
try {
Thread.sleep(3000);
Result result = new Result();
result.setId(System.currentTimeMillis());
result.setName(input.getName());
return result;
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
};
Thread workerThread = new Thread(task);
workerThread.setDaemon(true);
workerThread.start();
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Visibilty");
primaryStage.setScene(scene);
primaryStage.show();
}
private void updateGUI(Result result) {
System.out.println("result" + result);
}
public static void main(String[] args) {
launch(args);
}
private static class Input {
private long id;
private String name;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
private static class Result {
private long id;
private String name;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Result{" + "id=" + id + ", name=" + name + '}';
}
}
}
source
share