10

についていくつか質問がありPlatform.runLaterます。JavaFXアプリケーションクラスがあります。このクラスでは、スレッドを実行します(スレッドはネットワークソケットからデータを読み取ります)。

スレッド内に新しいものを作成するStageと、システムは実行をスローします(JavaFXイベントディスパッチャースレッドと私のnetork-readスレッドは同じではありません)-私はこの動作を理解しています。

しかし、反対側は、ネットワークリーダーからのテキストを既存のTextAreaものに追加するか、いくつかの項目を追加/削除しますListView<String>-これは例外をスローしません-なぜですか?JavaFXはシングルスレッド(UIライブラリ部分)だと思いました。これはSwingの場合と同じですか。動作する場合もあれば、ゴミだけが発生する場合もあります(EDTのため)。

私の質問:

  • JavaFXイベントディスパッチャスレッドはいつ例外をスローしますか?そうでない場合は?
  • これについての良い文書はありますか
  • Platform.runLaterメソッドで使用するより簡単な(より短く、よりクリーンな)方法はありrun()ますか?トライキャッチ(または複数のキャッチ)と組み合わせると、非常に奇妙に見えます

Platform.runLaterスレッドでの使用法はそれほど良くないことを知っています(設計ソリューション)

4

2 に答える 2

19

アレクサンダーの答えは、あなたの質問に関する最も重要な点を捉えています.

この回答は、いくつかの補足情報を提供します。

JavaFX イベント ディスパッチャー スレッドが例外をスローするのはいつですか。

JavaFX システムは、アクティブなシーン グラフに影響を与えるオブジェクトへのアクセスが JavaFX スレッドに適切に制限されていることを常にチェックするわけではありません。最終的に、このようなスレッドの安全性を確保するのは、JavaFX システムではなく、JavaFX アプリケーション プログラマの責任です。JavaFX でマルチスレッド プログラミングを実行するときは十分に注意する必要があります。そうしないと、アプリケーションの動作が失敗したり、予測不能になったりする可能性があります。

これに関する適切なドキュメントはありますか

JavaFX チュートリアル: Concurrency in JavaFX を試してください。

run() メソッドで Platform.runLater を使用する簡単な (より短くよりクリーンな) 方法はありますか?

No.Platform.runLaterはとてもシンプルです。


余談として 。. .

タスクとサービス

WorkerのTaskまたはServiceサブクラスの使用を検討してください。これらはFutureTask (これはRunnableです) の JavaFX ラッパーです。ワーカーは、バックグラウンド スレッドでロジックを実行するためのcallメソッドを提供します。それらは実行ステータスを維持し(状態変更のための JavaFX スレッドへのスレッドセーフなコールバック通知を使用して)、valuemessage、およびexceptionプロパティを介して呼び出しの結果を返します。

Taskおよびjavadoc の例のデザイン パターンを利用して、Service次のような機能を備えたスレッド セーフなアプリケーションを簡単に作成できます。

  • UI 更新のためのデータの非同期フェッチ。
  • タスクの進行状況に関する定期的なメッセージの更新。
  • 表示されたシーンにまだアタッチされていないノード グラフの作成。
  • プログレスバーなどによる進行状況の監視

AWorkerは を補完しPlatform.runLaterます。Platform.runLaterJavaFX アプリケーション スレッドから実行していて、JavaFX アプリケーション スレッドで何らかのロジックを実行する場合に使用します。WorkerJavaFX アプリケーション スレッドで実行していて、新しいスレッドでロジックまたは (特に) I/O を生成して、JavaFX アプリケーション スレッドをブロックしないようにする場合は、 a を使用します。Platform.runLaterのメソッド内でネットワーク I/O を実行したくはないでしょうが、のrunメソッドで実行したいことがよくあります。Workercall

また、 と の使用は の使用TaskService互換性がありませんPlatform.runLater。たとえば、実行時間が非常に長くTask、定期的に、またはバッファがいっぱいになったときに、部分的な結果を UI に返したい場合Platform.runLaterは、タスクのcallメソッドで実行するのがその方法です。

ワーカーは、ライブラリによって提供される既存のスレッド化されたサービスがなく、代わりに独自のスレッドを作成してバックグラウンドで実行する場合に役立ちます。既存のスレッド化されたサービスがある場合はPlatform.runLater、JavaFX アプリケーション スレッドでロジックを実行するために を使用する必要があります。

を使用する場合でも、何をしているのかを知る必要があることに注意してWorkerください アクティブなシーン グラフ上のノードを更新しないなど、標準の JavaFX 同時実行ルールに違反しないように注意する必要があります (アクティブなシーン グラフ内のノードがバインドされている値を更新しないことを含む -アイテムバッキングの観察可能なリストなど)。 ListView ) 。

于 2013-03-02T01:00:20.877 に答える
13

「これは例外をスローしません - なぜですか?」そのようなケースのすべてが咳をしているわけではないため...おそらく、パフォーマンス上の考慮事項のために、機能が失われている可能性があります。

JavaFX オブジェクトとのすべての対話 (作成を含む) は、JFX スレッドで行う必要があります。別のスレッドからこれらの JFX オブジェクトにアクセスする場合は、runLater または runAndWait メソッドを使用します。今例外をスローしなくても、将来例外をスローし始める可能性があります。JFX オブジェクトとのやり取りは、後続のアクションとイベントを引き起こす可能性があり、これはスレッド チェッカーによって確認されますが、確実ではありません。

これに関する適切なドキュメントはないと思います-単純なルール-runLaterまたはrunAndWaitを使用してください。

より短くよりクリーンな方法 - Lambda を使用して JDK 8 で提供されます。

于 2013-03-01T15:07:23.010 に答える