在我的项目中,我正在使用Akka的演员。根据定义,Actors是线程安全的,这意味着在Actor的 receive 方法中
def receive = {
case msg =>
// some logic here
}
一次只有一个线程处理注释的代码段。但是,当这段代码异步时,事情开始变得更加复杂:
def receive = {
case msg =>
Future {
// some logic here
}
}
如果我理解正确的话,在这种情况下,只有Future构造才会被同步,而不是逻辑里面未来。
当然,我可以阻止未来:
def receive = {
case msg =>
val future = Future {
// some logic here
}
Await.result(future, 10.seconds)
}
解决了这个问题,但我认为我们都应该同意这不是一个可以接受的解决方案。
所以这是我的问题:在异步计算没有阻止Scala的期货的情况下,如何保留参与者的线程安全特性?
答案 0 :(得分:6)
如果有的话,我如何保留演员的线程安全性 没有块Scalas
的异步计算Future
?
这个假设只有在你修改Future
里面的演员的内部状态时才会出现,这似乎是一个设计气味。仅使用未来进行计算,方法是使用pipeTo
创建数据的副本并将管道计算结果传递给actor。一旦演员收到计算结果,你就可以安全地对其进行操作:
import akka.pattern.pipe
case class ComputationResult(s: String)
def receive = {
case ComputationResult(s) => // modify internal state here
case msg =>
Future {
// Compute here, don't modify state
ComputationResult("finished computing")
}.pipeTo(self)
}
答案 1 :(得分:0)
我认为您需要首先“解析”db查询,然后使用结果返回新的SELECT mdkamvp.mdkamda_sid,
(SELECT DISTINCT first_value(subject) over (partition BY subject
ORDER BY dateto DESC)
FROM mdkndlst
WHERE subject IS NOT NULL ) naktion,
mdkamvp.rowid row_id
FROM springv2.mdkamvp
ORDER BY mdkamvp.indstatus
。如果db查询返回Future
,那么您可以使用Future[A]
对flatMap
进行操作并返回新的A
。
Future
答案 2 :(得分:0)
这里最简单的解决方案是将actor转变为状态机(使用AkkaFSM)并执行以下操作:
取决于上下文,您可能需要做更多工作才能获得正确的响应。
但是这样做的好处是你可以使用actor状态处理消息,并且可以随心所欲地改变actor状态。