我试图通过阅读文章javafx concurrency来弄清楚javafx中并发是如何工作的,但是,我想知道如何在call
方法FutureTask
中更新全局静态变量的值。 1}}对象?这是一个简单的例子来理解我在说什么;
public class Sample extends Application {
static int x = 5;
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
FutureTask<String> futTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("in thread");
x = 6;
return "foobar";
}
});
Platform.runLater(futTask);
if( futTask.isDone() )
System.out.println("Done" + " x = " + x);
}
所以,futTask.isDone()
永远不会返回true。我可以理解,也许futTask还没有完成它的过程,或者由于Platform.runLater
而未被调用。但是,“在线程中”字符串打印在控制台上,那么为什么x不会更新为6?
答案 0 :(得分:1)
你的错误是你在调用Platform.runLater()之后立即检查了isDone(),此时还没有调用FutureTask。该程序显示它实际上正在更新x,但稍后:
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
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.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class FutureTaskTest extends Application {
public static void main(String[] args) {
launch(args);
}
static int x = 5;
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
FutureTask<String> futTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("in thread");
x = 6;
return "foobar";
}
});
Platform.runLater(futTask);
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
System.out.println(" x = " + x);
}
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
}
输出:
x = 5
x = 5
x = 5
in thread (clicked button here)
x = 6
x = 6
x = 6