Platform.runLater が現在 JavaFX スレッド上にあるかどうかをチェックしないのはなぜですか?

StackOverflow https://stackoverflow.com//questions/24043420

  •  21-12-2019
  •  | 
  •  

質問

JavaFX 8 を使用する場合、GUI との対話を実行する必要があります。 Platform.runLater, そうでない場合、別のスレッドから実行すると例外がスローされます。

ただし、実装は Platform.runLater 現在 JavaFX スレッド上にあるかどうかは決してチェックしません。

次のメソッドを書きました。

public static void runSafe(final Runnable runnable) {
    Objects.requireNonNull(runnable, "runnable");
    if (Platform.isFxApplicationThread()) {
        runnable.run();
    }
    else {
        Platform.runLater(runnable);
    }
}

これにより、fx アプリケーション以外のスレッドでは実行できなくなります。

デフォルトの実装がこの種の短絡を行わない理由はありますか?

役に立ちましたか?

解決

runLater 基本的に、FX スレッドが使用可能になったときに Runnable を実行用のキューに入れます。このメソッドには、FX 以外のスレッドを通じてアクセスできます。他のスレッドがタスクを runLater キューに入れてから電話をかける runLater この場合も、FX スレッドからかどうかに関係なく、新しいタスクをそのキューの末尾に配置する必要があります。

あなたが提案する短絡では、以前のタスクの優先順位は基本的に低くなり、望ましくない可能性があります。

他のヒント

関数を呼び出すとき、その関数が 'runLater' と呼ばれる場合、それは今ではなく後で実行されることが期待されます。

名前からすると、実装は正しいことをしているように思えますが、 そしてそれはドキュメントです:

将来の不特定の時点で、JavaFX アプリケーション スレッド上で指定された Runnable を実行します。

このメソッドは任意のスレッドから呼び出すことができ、Runnable をイベント キューにポストし、すぐに呼び出し元に戻ります。ランナブルは、投稿された順序で実行されます。runLater メソッドに渡された Runnable は、後続の runLater 呼び出しに渡された Runnable よりも前に実行されます。

コードを後で実行したくない場合は、後で実行するように要求しないでください。これがコードで本質的に行ったことです。

電話をかけている人を見たことがある EventQueue.invokeLater Swing の EDT から時々...規範によれば、それは合法的な技術です。したがって、私がよほど間違っていない限り、これは JavaFX でも同じ状況です。

しかし、個人的にはこの手法には疑問を感じます。見る この質問:選択された答えは使用します invokeLater なぜなら selectAll() 呼び出される前に、現在のすべての EDT イベントが自動的に完了する必要があります。このソリューションは実際に次のことを保証します selectAll ここで他の EDT コードが発生する前に実行することはできません。

しかし、この答えには脆弱性があると私は主張します。私が提案した答えを参照してください(Jythonで書かれていますが、理解できるはずです)。誰かが「編集を開始するためのクリック数」を 1 に設定したとします。さらに恐ろしいことに、二人の間で何か予期せぬことが起こったとします。 invokeLater そしてその selectAll. 。代替メカニズムがまったくないという確信がある場合、または 2 つのスレッドのイベントとオブジェクトが完全に「切り離されている」という確信がある場合を除き、個人的には呼び出すことは避けるべきだと思います。 runLater JavaFX スレッドから。

同時実行性は常にあなたを攻撃するのを待っています。したがって、このようなテクニックは細心の注意を払って使用してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top