Scala演员-最糟糕的做法?

Scala演员-最糟糕的做法?,scala,akka,actor,Scala,Akka,Actor,我觉得在Scala中使用演员有点不安全。我已经阅读了关于如何做事情的文档,但我想我还需要一些禁忌规则,以便能够自由地使用它们。 我想我担心我会以错误的方式使用它们,我甚至不会注意到这一点 你能想到一些东西,如果应用,会破坏Scala参与者带来的好处,甚至是错误的结果吗 我知道这并不能真正回答问题,但您至少应该鼓起勇气,基于消息的并发比基于共享内存线程的并发更不容易出现wierd错误 我想您已经在Scala编程中看到了演员指南,但请注意: 参与者在处理消息时不应阻塞。在您可能要阻止的位置,请尝试

我觉得在Scala中使用演员有点不安全。我已经阅读了关于如何做事情的文档,但我想我还需要一些禁忌规则,以便能够自由地使用它们。 我想我担心我会以错误的方式使用它们,我甚至不会注意到这一点


你能想到一些东西,如果应用,会破坏Scala参与者带来的好处,甚至是错误的结果吗

我知道这并不能真正回答问题,但您至少应该鼓起勇气,基于消息的并发比基于共享内存线程的并发更不容易出现wierd错误

我想您已经在Scala编程中看到了演员指南,但请注意:

  • 参与者在处理消息时不应阻塞。在您可能要阻止的位置,请尝试安排稍后获取消息
  • 尽可能使用
    react{}
    而不是
    receive{}
  • 仅通过消息与参与者沟通
  • 喜欢不可变的消息
  • 使消息独立
      • 避免
        只要可能。你会得到一个锁定的系统

      • 始终从参与者子系统线程发送消息。如果这意味着通过
        Actor.Actor
        方法创建一个临时Actor,那么就这样吧:

        case按钮点击(src)=>Actor.Actor{controller!SaveTrade(trdFld.text)}

      • 在参与者的反应中添加“任何其他消息”处理程序。否则,无法确定您是否向错误的参与者发送了信息:

        case other=>log.warning(此+“已收到意外消息”+other

      • 不要对主要参与者使用
        Actor.Actor
        ,而应使用subcass
        Actor
        。原因是只有通过子类化,才能提供合理的
        toString
        方法。同样,如果日志中充斥着以下语句,调试参与者非常困难:

        12:03[INFO]向scala.actors.Actor$anonfun$1发送请求交易(2009-10-12)

      • 记录系统中的参与者,明确说明他们将收到什么消息,以及他们应该如何精确计算响应。使用参与者会导致标准过程的转换(通常封装在方法中)要成为跨多个参与者反应的逻辑,没有好的文档很容易迷失方向

      • 始终确保您可以在参与者的
        react
        循环之外与参与者进行通信,以查找其状态。例如,我始终声明一个方法,该方法将通过
        MBean
        调用,该方法类似于下面的代码段。否则,很难判断参与者是否正在运行、是否已关闭、是否有大量的我信使等

      • 将您的参与者链接在一起并使用
        trapExit=true
        ——否则他们可能会无声地失败,这意味着您的程序没有按照您认为的那样运行,并且可能会随着消息留在参与者邮箱中而耗尽内存

      • 我认为,围绕使用参与者做出的设计决策,还有一些有趣的选择已经得到了强调和讨论


      您好,谢谢您的快速回答-这是非常有用的观点。我认为“共享状态”也是不应该做的事情。但我不知道这在代码级别意味着什么-也许,-作为消息的类C带有一个私有字段F和一个用于该字段的经典getter(getF)-从一个参与者发送一个C实例-从该参与者发送一个C实例,接收C并调用getF?这是否意味着“共享状态”?谢谢!共享状态是由多个线程访问的状态。它不像共享可变状态那么糟糕,但它需要对一致性进行推理,除非只有在构造和enceforth不可变。因此,在消息中发送对您自己的引用不是最明智的做法,尽管对可变对象的引用比对不可变对象的引用更糟糕。您的其他要点立即就有了意义,但我很好奇您的第二点,即始终从参与者线程内发送消息。问题是什么这里的主要动机是性能/清晰度/其他方面?我不太明白。我看到你在Scala中编写演员代码时经历了很多痛苦!:-)@Michael-如果你自己没有明确声明演员,那么会为你创建一个演员,并作为
      ThreadLocal
      绑定到
      Thread
      。我一点也不清楚这种方法在逻辑上是安全的还是没有内存泄漏。显式声明一个
      (myActor.getState==scala.actors.Actor.State.Suspended)
      在参与者在
      react
      中等待时为true,那么我们真的需要您建议的方法来查找状态吗?这个问题中的代码有任何问题吗?
      def reportState = {
        val _this = this
        synchronized {
          val msg = "%s Received request to report state with %d items in mailbox".format(
                         _this, mailboxSize) 
          log.info(msg)
        }
        Actor.actor { _this ! ReportState }
      }