JavaFx2 または ScalaFx + Akka 質問する

JavaFx2 または ScalaFx + Akka 質問する

JavaFX/ScalaFX アプリケーションで Akka アクターを実行するにはどうすればいいですか?

(これは最初の回答に基づいた質問の更新です)

解決策は同じ実行コンテキストを共有することですか? つまり、JavaFx ExecutorService に基づくアクターディスパッチャーを持つということですか? (UI 操作コードを実行するもの)

それは、1 つのエージェントが UI を表し、それを操作できることを意味しますか? つまり、以下で示唆されているように、複数のアクターが UI ExecutorService 上にある場合、エージェント間で状態を共有すること (オブジェクトは UI) を意味しませんか?

2 人のアクターは、異なるエグゼキュータ サービス上で通信できますか? この質問をしているのは、以下で示唆されていることから、一部のエージェントは UI エグゼキュータ サービス上にあり、他のエージェントはそうではないと考えられるためです。

最後に、Executor コンテキストが異なる akka をそのまま使用し、Platform.runLater を使用すると、UI のパフォーマンスに何らかの影響が出る可能性があるのはなぜでしょうか。これにより、同じアプリケーションで複数の executor サービスを使用することは悪いことなのかという疑問が生じます。

ベストアンサー1

  • 先物

scala Futures を JavaFX などのシングルスレッド ツールキットと一緒に使用する最善の方法は、UI ツールキットのスレッドで Futures またはアクターを実行できるエグゼキュータを定義することです。

Swingにも同じ問題があり、Swingスレッドで更新を行う必要があります。Viktor Klangは次の解決策を思いつきました。スイング実行コンテキスト以下は JavaFX 用に翻訳したものです:

import akka.dispatch.ExecutionContext
import javafx.application.Platform
import java.util.concurrent.Executor

//
object JavaFXExecutionContext {
  implicit val javaFxExecutionContext: ExecutionContext = ExecutionContext.fromExecutor(new Executor {
  def execute(command: Runnable): Unit = Platform.runLater(command)
  })
}

次のように使用します:

// import the default ec
import scala.concurrent.ExecutionContext.Implicits.global
// define the JavaFX ec so we can use it explicitly
val fxec = JavaFXExecutionContext.javaFxExecutionContext
future {
  // some asynchronous computation, running on the default
  // ForkJoin ExecutionContext because no ec is passed
  // explicitly
}.map(result => {
  // update JavaFX components from result
  // This will run in the JavaFX thread.
  // Check Platform.isFxApplicationThread() to be sure!
})(fxec)

JavaFX コンポーネントと対話するステップがすべて JavaFX ExecutionContext 上で実行されている限り、futures のパイプラインは非常に複雑になる可能性があります。

注: ForkJoin ec をデフォルトにして JavaFX ec を明示的に渡すか、その逆を行うかはあなた次第です。エラーを防ぐために JavaFX ec をデフォルトにして、非同期で実行できる部分を ForkJoin ec で明示的にマークすることをお勧めします。

  • 俳優

アクターベースのシステムをシングルスレッドUIツールキットと統合するためのソリューションもあります。スウィング俳優交換するだけです

SwingUtilities.invokeLater(command)

Platform.runLater(command)

これで準備完了です!

  • いつ使うか

大きなUIアプリケーションがあり、非同期操作(ファイルの読み込みや計算の実行)を分離したいだけの場合は、フューチャーベースのアプローチがおそらく望ましいでしょう。ただし、どれでもデフォルトの実行コンテキストで非同期に実行される futures 内の JavaFX コンポーネントとの対話 (読み取りも書き込みもなし)。

大規模なアクター ベースのシステムがあり、一部の部分に UI をアタッチしたいだけの場合は、JavaFX スレッドで実行されるアクターをいくつか用意することが望ましいでしょう。結果は人によって異なります。

おすすめ記事