Akka Actor如何在线程之间进行交互?

9

我已经阅读了akka文档,但无法理解在使用akka时线程交互的清晰性。文档可能会忽略这一点,认为这是显而易见的,但对我来说并不是那么明显。

所有的akka actor似乎都在它们被调用的同一个线程中运行。我将actor视为协作过程,每次接收调用时都有自己的堆栈重置。

您可以执行一长串沿直线切换的actor链。每个接收操作执行小型非阻塞操作,并强制另一个接收操作继续工作。没有事件循环,可以处理actor系统外的消息。

我想捕获来自其他线程的请求,执行控制操作,并等待另一个消息。

以下是一些概述我的需求的用例。

  1. 有一个线程不断从某些源轮询数据。一旦数据匹配模式,它就会基于actor调用事件驱动处理程序。逻辑控制器做出决策并将其传递给工作者。应该有两个持久线程。一个线程在轮询上不断工作,另一个线程异步地控制它的工作。不能让akka actors进入第一个线程,因为它们会破坏轮询周期,第一个线程也不应阻塞actors,因此需要另一个线程。

  2. 有一种双面棋盘游戏。一侧有一个控制器线程,它安排计算时间工作与棋盘服务器交互等等。另一个线程是一个重型计算线程,循环遍历不同的变体,无法写入akka,因为它具有阻塞性质。

我知道现有的akka futures,但它们代表一次触发后运行并在执行目标后关闭的工作任务。Futures与akka actors结合得很好,但不能表示循环工作线程。

Akka actor系统包含不同类型的网络事件循环。您可以使用其内置的远程actor系统或众所周知的0mq协议。但对于线程交互使用网络似乎过度了。

粘合非akka线程和akka线程的预期方法是什么?我应该编写一些特殊的程序以线程安全的方式执行消息传递吗?


1
不过,我认为我们没有忽略太多:http://akka.io/docs/akka/2.0-RC4/scala/dispatchers.html - Roland Kuhn
1
再做一个更正:Akka Actor 不会在调用它们的同一线程上运行,请参考我之前的评论中的文档。Actor 不是协程。JVM 不支持“堆栈重置”这个概念。Actor 模型是比线程更高层次的抽象。向 Actor 传递消息始终是线程安全的(请参见 ActorRef.tell())。 - Roland Kuhn
我建议您查看Akka与Apache Camel集成,以了解如何响应外部事件。书籍《Akka Essentials》http://www.packtpub.com/akka-java-applications-essentials/book清晰地描述了线程模型,并提供了大量可运行的示例代码,涵盖Java和Scala两种语言,以便掌握所有基础知识。 - simbo1905
simbo1905:我发现了将Akka嵌入其他本地线程的最有机的方法:https://gist.github.com/viktorklang/2422443 - ayvango
1个回答

5
如果您需要轮询,则轮询线程应该将任何被轮询的内容转换为消息并发送给一个actor。
我认为更有用的方法是使用具有接收超时的Actor进行间隔非阻塞轮询,当有被轮询的内容时,它将发布到其他actor或者甚至其ActorSystems的EventStream,以实现真正的发布-订阅操作。

我已经读了几遍(针对新版本的Akka),但仍然错过了线程架构描述。 - ayvango
2
如果你告诉我线程架构描述实际上是什么,那么我会解释。 - Viktor Klang
1
线程演员在哪个线程中运行?如果在线程上触发了消息,它会在这个线程中处理还是在另一个线程中处理?最简单的架构不需要线程支持,演员作为协同程序在发出它们的线程中使用,将消息存储在特殊邮箱中,然后按顺序调用所有需要的演员以响应提供的消息,直到队列变为空(如果没有循环和阻塞)。然后,由于第一条消息是从演员系统外部触发的,因为演员是按需调用的,所以演员系统将流程控制返回到它被调用的点。 - ayvango
以上的方法完全符合演员模型,但非常基础。您可以采用另一种方法:为演员处理创建一个单独的线程(或者可能是一组工作线程),并使用线程安全的消息触发方法。在这种情况下,将消息安全地传输到队列中的演员系统线程之外的块,并立即恢复命令流。这种方式更加棘手和灵活。 - ayvango
2
请问是哪本书的哪一页? - Viktor Klang
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接