JavaFx2或ScalaFx+;阿克卡
如何在JavaFX/ScalaFX应用程序中运行Akka actors (这是基于第一个答案的问题更新) 解决方案是否共享相同的执行上下文?意思是让参与者调度器基于JavaFXExecutorService?(用于运行UI操作代码的代码) 这是否意味着一个代理将代表UI并能够操纵它?我的意思是,因为下面建议,如果两个参与者在UI ExecutorService上,这不意味着在代理之间共享一个状态(对象就是UI)吗 两个参与者在使用不同的executor服务时是否可以通信?我这样问是因为根据下面的建议,一些代理将在UI Executor服务上,而另一些则不在JavaFx2或ScalaFx+;阿克卡,scala,javafx,javafx-2,akka,scalafx,Scala,Javafx,Javafx 2,Akka,Scalafx,如何在JavaFX/ScalaFX应用程序中运行Akka actors (这是基于第一个答案的问题更新) 解决方案是否共享相同的执行上下文?意思是让参与者调度器基于JavaFXExecutorService?(用于运行UI操作代码的代码) 这是否意味着一个代理将代表UI并能够操纵它?我的意思是,因为下面建议,如果两个参与者在UI ExecutorService上,这不意味着在代理之间共享一个状态(对象就是UI)吗 两个参与者在使用不同的executor服务时是否可以通信?我这样问是因为根据下面的
最后,为什么按原样使用akka(其on Executor上下文不同)并使用Platform.runLater,可能会对UI的性能产生一些影响。我在同一个应用程序中提出了多个执行器服务的问题:这是坏的吗?< /P> < P>在JavaFX中使用多个线程时需要考虑的两个问题:
- 任何最终接触到场景图的代码(例如,通过更新绑定到控件的数据)都必须包装在
中。如果您在JavaFX中使用内置多线程API(即Platform.runLater
和任务
),这将自动完成,但如果您使用任何其他多线程实用程序,则必须自己完成服务
- 您的多线程实用程序(即Akka)必须(我认为)以某种方式被告知为JavaFX事件线程留出一些空间。如果您查看源代码,您会发现他们在配置执行器时非常小心。我不确定这方面的细节,但当我尝试使用Scala的
s和JavaFX时,我发现在使用默认的Future
时,UI中出现了一些无响应的情况,当我使用基于ExecutionContext
实现的自定义上下文时,这种情况消失了服务
- 未来
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组件交互的步骤都在JavaFXExecutionContext上运行,未来的管道就可能非常复杂
注意:是否将ForkJoin ec设置为默认值并显式传递JavaFX ec取决于您自己,反之亦然。将javafxec设置为默认值可能是一个好主意,以防止出现错误,并标记可以使用ForkJoin ec显式异步运行的部分
- 演员
SwingUtilities.invokeLater(command)
与
你可以走了
- 什么时候用哪个
如果您有一个大型的基于actor的系统,并且只想将UI附加到某些部分,那么在JavaFX线程上运行几个actor可能是更好的选择。YMMV.是关于akka演员的要点,可以在Swing或JavaFX线程上运行。这是Victor Klang基于的一个方便、可复制的扩展。是的,这是可能的。我已经使用Scala、Akka和ScalaFX编写了三到四个应用程序供内部使用。编写JavaFX/ScalaFX多线程应用程序与编写任何其他多线程应用程序没有太大区别。您是否有任何具体问题导致您首先提出此问题?我这样问是因为在目前的表格中,您的问题IMO不适合Stackoverflow。如果您对使用scala、akka和scalafx的示例应用程序感兴趣,您可以查看。这是我为测试scala、akka和scalafx而创建的一个简单的俄罗斯方块游戏。两个演员可以在不同的executor服务上交流吗?是的,看这张照片。它在同一执行上下文上生成模型参与者,在JavaFx执行上下文上生成视图参与者。他们都可以互相交流。谢谢你的详细解释。我不确定是否完全理解演员的解决方案。你能解释一下让AKKA参与者的executionContext不同于JAVAFX的根本问题是什么吗?或者我说是遗嘱执行人?建议解决方案的主要目标是什么?什么时候您需要在与JavaFXUI线程相同的executorService上使用actor?如果您运行配置了默认执行上下文的actor,它将在线程池线程上执行。但是,不允许从任意线程修改甚至访问JavaFXGUI组件的状态,这将导致未定义的行为。因此,诀窍是配置所有以某种方式与GUI交互的参与者,以便使用JavaFXExecutionContext在GUI线程上执行。这样,您就拥有了一个行为与任何其他行为类似的行为(您可以安全地传递其ActorRef),但可以从其receive方法内部安全地访问GUI状态。是否可以从代理内部使用Platform.runlater更新
Platform.runLater(command)