0

我试图通过阅读文章javafx concurrency来弄清楚并发在 javafx 中的工作原理,但是,我想知道如何在对象call方法中更新全局静态变量的值FutureTask?这是一个简单的例子来理解我在说什么;

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. 但是,“in thread”字符串打印在控制台上,那么为什么 x 没有更新到 6 呢?

4

1 回答 1

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
于 2013-09-02T13:00:04.513 回答