java - 为什么 akka 需要不可变消息

标签 java scala thread-safety akka immutability

或者换句话说:是否正确使用了可变消息?

我面临的用例是我想处理基本上是类型的对象

Map<String,List<String>>

actor 执行的典型处理是读取或写入 map 的某些字段。一个浓缩的例子是(省略 null-tests 等)

  map.get("somekey").add("new value");

我的预感是,通过使用各自的集合类型,在 Scala 中保持此不可变是微不足道的。在 Java 中,它需要一些额外的类库。

但是:阅读 Akka 文档,我发现 sending a message introduces a happens-before relation在发送者的最后一次访问和接收者的第一次访问之间。因此,如果 map 不是不可变的,那么发送方应该可以看到所有数据。

假设我可以确保发送方在 map 发送后不会再触及它,是否还有关于此 map 的线程数据访问的任何其他问题?

最佳答案

OP 对 happens-before 规则的解释是正确的:“actor 发送规则”意味着将 M 发送给 actor A happens-before A 处理 M(这就是“相同”所指的)。

回答主要问题:只要在任何给定时间点最多只有一个参与者可以“拥有”可变 map ,这就可行,并且根据具体情况,这可能是最有效的解决方案问题。不过,保证单一所有权需要一些纪律,这会通过维护成本抵消运行时优势。

虽然最初的问题遗漏了传输 Map 的实际工具,但我想强调 Randall 的观点,即参与者之间的消息永远不应该是 JDK 类型,因为它们缺乏语义。在这种情况下,Map 应该包含在一个明确命名的自定义消息类型中。

关于java - 为什么 akka 需要不可变消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23564049/

相关文章:

java - 关于 Google Web Toolkit (GWT) 和 HTML 页面中动态数据预处理的问题

java正则表达式括号

scala - 将 RDD[(Long,Long)] 转换为 RDD[Row]

java - NonFatal 捕获 Throwable 可以吗?

java - 线程安全的枚举单例

c++ - 全局变量构造函数/析构函数是否需要线程保护?

java - 如何创建 react 性 'intermediate subscriber' ?如何将所有 Flux<T> 部分和它们的处理结果在链中进一步组合(转换为 Mono<R>)?

java - 向旧版 Swing 应用程序添加触摸手势

scala - Play /记录/打印响应正文/遍历枚举器/缓冲正文

java - 同步块(synchronized block)中List的数据重叠