如何在FutureTask的调用方法中更新全局变量的值

时间:2013-09-02 12:49:57

标签: multithreading concurrency javafx-2 task futuretask

我试图通过阅读文章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?

1 个答案:

答案 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