【问题标题】:Akka actors concurrency issueAkka演员并发问题
【发布时间】:2013-03-24 10:07:46
【问题描述】:

假设我有三个 Actor 相互通信:ActorControl、ActorA、ActorB。

ActorA 和 ActorB 与 ActorControl 通信。他们收到的消息大多不同,但他们也有一个相同的消息 X。当他们得到 X 时,他们都需要执行功能 Y。

为避免重复代码,我取出函数 Y 来封装名为 common 的对象。

在这种情况下,ActorA 和 ActorB 可能同时调用 common.Y。

我的问题是这样我是否会破坏演员的并发性?

【问题讨论】:

    标签: scala akka actor


    【解决方案1】:

    您可以在参与者之间共享代码,但不能共享数据。如果你的函数是纯函数(无状态且没有副作用),那么就没有任何问题。

    这里有一些例子:

    object Helper {
    
      // Safe
      def incrementPure( total: Int, i: Int ) = total + i
    
      //Unsafe
      private var total = 0
      def incrementStateful( i: Int ) = { total += i; total }
    
      //Unsafe
      def incrementSideEffect( i: Int ) = {
        val total = readCurrentTotal()
        val total2 = total + i
        saveCurrentTotal( total2 )
        total2
      }
    
    }
    

    在最后两个函数中,您应该提供某种同步。但是,如果您依赖并行性,这可能会影响性能。

    【讨论】:

    • 如果它们不是纯的,如果我使用具有相同代码的两个函数或如果我使用一个“共享”函数有区别吗?
    • @tzofia 是的,如果它们不是纯粹的,您可能会遇到问题,但有几个可能的解决方法。如果您提供更多信息,我(或其他人)或许能够为您的问题提供解决方案。
    • 你能举个例子说明使用一个函数或两个equals函数(当函数不是纯函数时)会有区别吗?我无法理解为什么会有不同...
    • @tzofia 这里有一些例子。这些是常见的并发/分布式计算/并行陷阱。
    • @tzofia 在第二个示例中,如果您复制代码,您将有两个 total 变量,这使其安全(但可能需要在某处进行聚合。在示例中,您需要将复制总数,例如获得真实总数)。第三种情况在两种情况下都是不安全的(复制或共享)。
    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2015-03-28
    • 2014-03-09
    • 2019-01-16
    相关资源
    最近更新 更多