JavaFX 同時実行性という用語は、マルチスレッドと同時実行性に関して JavaFX がどのように設計されているかを指します。この JavaFX 同時実行チュートリアルでは、JavaFX スレッド モデルについて説明します。
Java 同時実行とマルチスレッドを初めて使用する場合は、このテキストのスペースよりも詳細に Java 同時実行の仕組みを説明した長いJava 同時実行チュートリアルを用意しています。
シングルスレッドレンダリング
JavaFX はシングルスレッドのレンダリング設計を使用しています。つまり、単一のスレッドだけが画面上に何かをレンダリングできます。それが JavaFX アプリケーション スレッドです。実際、一般的にJavaFX シーン グラフに変更を加えることができるのは JavaFX アプリケーション スレッドだけです。
シングルスレッドのレンダリング設計は正しく実装するのが簡単ですが、JavaFX アプリケーション スレッド内で長時間実行されるタスクでは、タスクが完了するまで GUI が応答しなくなります。JavaFX アプリケーション スレッドがそのタスクの実行でビジー状態の間、JavaFX GUI コントロールはマウスのクリック、マウス オーバー、キーボード入力に反応しません。
Platform.runLater()
場合によっては、JavaFX アプリケーションで長時間実行されるタスクを実行することが絶対に必要になることがあります。タスクの実行中に GUI を応答しないままにしたくないため、独自のスレッドで ask を実行したいとします。ただし、実行中のタスクの途中またはタスクの完了時に GUI を更新したいとします。タスク スレッドは GUI (シーン グラフ) を直接更新できませんが、JavaFX にはこの問題に対する解決策があります。
JavaFXにはメソッドをPlatform
持つクラスが含まれていますrunLater()
。このrunLater()
メソッドは、時間のあるときに JavaFX アプリケーション スレッドによって実行される Runnable を受け取ります。この Runnable 内から JavaFX シーン グラフを変更できます。以下は、そこから ProgressBar コントロールを呼び出して更新することによって、実行中にJavaFX ProgressBar を更新するタスク スレッドを示す例です。Platform.runLater()
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ConcurrencyExample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("JavaFX App");
ProgressBar progressBar = new ProgressBar(0);
VBox vBox = new VBox(progressBar);
Scene scene = new Scene(vBox, 960, 600);
primaryStage.setScene(scene);
primaryStage.show();
Thread taskThread = new Thread(new Runnable() {
@Override
public void run() {
double progress = 0;
for(int i=0; i<10; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress += 0.1;
final double reportedProgress = progress;
Platform.runLater(new Runnable() {
@Override
public void run() {
progressBar
.setProgress(reportedProgress);
}
});
}
}
});
taskThread.start();
}
}