scala 中的原子函数/方法(不引入 actor 系统开销)

mat*_*ter 0 scala akka

我目前使用 Akka actor 建立一个以线程安全方式原子执行的代码块(Akka 邮箱语义通过一次处理一条消息来强加原子性)。

然而,这引入了对参与者系统的需求,以及额外的副作用或膨胀(必须手动将异常传播给调用者,失去类型安全性ask,并且通常使用消息语义而不是函数调用)。

是否可以在scala中以更简单的方式完成线程安全的原子代码块?你会应用@volatile到一个函数吗?

dk1*_*k14 5

这取决于您想要在这里保护哪种共享状态:

  • 最简单且通用的选择是使用相同的旧版本synchronized。然而,与 Akka 不同的是,它是完全阻塞的,因此可能很容易降低你的性能,当然还有代码风格,因为很难控制混乱的副作用。它还可能允许死锁

  • Java 的是相同的方法,但性能可能会更好一些。

  • 另一种选择是相同的旧 Java AtomicReference(实现 CAS 操作)和相关类。积极的一面是它们是非阻塞的——开发人员实际上使用它们来构建高性能的集合。这里描述了锁和CAS的使用方法。它们都是相当低级的机制,所以我不建议过多使用它们,特别是对于业务逻辑(任何参与者的实现都会更好)。

  • 如果您的共享状态是一个集合 - 您可能需要使用相同的旧 Java 并发集合(它们具有原子操作,例如putIfAbscent)。例如,Scala 有有趣的非阻塞TrieMap 。

  • Scala STM也是一种替代方案

  • 最后,这个问题专门针对轻量级参与者模型实现。

PS Volatile 注解只不过是volatileJava 中的关键字模拟。您可以将其放在方法上,因为任何注释都可以放在任何东西上。