Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Akka:跨参与者实例共享状态_Java_Akka - Fatal编程技术网

Java Akka:跨参与者实例共享状态

Java Akka:跨参与者实例共享状态,java,akka,Java,Akka,MyMyProcessingActoractor将使用实体ID上的ConsistentHashingRouter进行路由,这样在任何时间(跨多个线程)都可能有此actor的多个实例在处理中 参与者使用映射来执行某些计算逻辑。因此,两个不同的参与者实例可以同时读取和写入此映射 跨这些actor实例共享映射似乎是对actor模型的公然违反,即使它是JavaConcurrentHashMap 处理这类问题的最佳选择是什么?我没有在Akka文档中看到它的地址,除非我错过了这个 我可以看到两种选择: My

My
MyProcessingActor
actor将使用实体ID上的
ConsistentHashingRouter
进行路由,这样在任何时间(跨多个线程)都可能有此actor的多个实例在处理中

参与者使用映射来执行某些计算逻辑。因此,两个不同的参与者实例可以同时读取和写入此映射

跨这些actor实例共享映射似乎是对actor模型的公然违反,即使它是Java
ConcurrentHashMap

处理这类问题的最佳选择是什么?我没有在Akka文档中看到它的地址,除非我错过了这个

我可以看到两种选择:

  • MyMapManagerActor
    的单个实例,用于管理对此映射的读取/写入。如果这是单线程的,那么实际上
    MyProcessingActor
    也将是单线程的
  • Akka STM的使用-我在项目的最新版本中没有看到这一点

  • 还有其他推荐的方法吗?

    如果映射是Actor实例上的一个字段,那么将有两个映射,并且不会发生跨线程问题。如果地图是共享但只读的,那么您仍然可以。如果映射是共享的,并且两个参与者都写入映射,那么您肯定需要使用ConcurrentHashMap进行锁定。

    正如您在问题中所说,在参与者之间共享可变状态是一件非常糟糕的事情。我使用了您提到的两种方法(使用
    mapmanagerator
    和使用Akka STM),这两种方法都可以工作,尽管
    mapmanagerator
    方法让我感觉更好。就
    mapmanagerator
    而言,唯一序列化的部分是对映射的实际读写,而不是计算本身,因此根据您的用例,您可能会发现并行化已经足够了

    另一种选择是用参与者替换地图本身。您可以有一个管理子级的父级参与者,每个映射条目有一个该参与者的子级。如果密钥集是静态的,则可以在启动时预先创建所有子参与者,例如使用密钥(或其哈希代码)作为参与者名称。然后可以使用
    actorSelection
    直接访问子参与者,如
    /user/parentActor/
    中所示。如果需要动态创建参与者,最好向父参与者请求一个特定的子级,并让其使用
    ActorRef
    回复该特定子级(必要时创建它)。比如:

    override def receive = {
      case GetActor(key) =>
        context.children(key) match {
          case Some(ref) => sender ! GetActorReply(ref)
          case None => sender ! context.actorOf(ChildActor.props, key)
        }
      }
    }
    

    然后,
    MyProcessingActor
    可以使用该
    ActorRef
    进行所有处理。

    不幸的是,这在Akka似乎是一件非常困难的事情。创建一个参与者来管理对地图的访问被证明是相当麻烦的,而且STM在最新版本中似乎不受支持


    因此,这里的解决方案是仔细选择
    ConsistentHashingRouter
    的密钥,这样在读取和写入地图时就不会有任何竞争条件。所讨论的映射是一个
    ConcurrentHashMap

    当参与者实际运行时,它在某个执行器上作为一个
    Runnable
    运行。按顺序运行一组合作参与者的诀窍是为每一组参与者提供一个专用的串行执行器-请参见。

    我对Akka没有太多经验,但一直在研究它。你所描述的似乎与阿克卡想要融入的范式背道而驰。也许您可以在消息中传递路由映射并使其不可变。如果你通过地图,地图也应该是不可变的。你看过阿克卡特工吗?它们可能有助于解决这类问题您在这里没有真正回答问题,只是重复了问题已经说明的内容。“还有其他推荐的方法吗?”没错。我要指出的是,如果地图不被共享,就不会有冲突。因此,不需要另一种方法。如果要共享映射,那么ConcurrentMap将是正确的方法。这些是共享的:因此,两个不同的参与者实例可以同时读取和写入映射。