scala 中的 Atomic function/method(不引入 actor 系统开销)
Atomic function/method in scala (without introducing actor system overheads)
我目前使用 Akka actor 来建立一个以线程安全方式原子执行的代码块(Akka 邮箱语义通过一次处理一条消息来强加原子性)。
然而,这引入了对 actor 系统的需求,以及额外的副作用或膨胀(必须手动将异常传播给调用者,在 ask
上失去类型安全,并且通常使用消息语义而不是函数调用)。
线程安全的原子代码块能否在scala中以更简单的方式实现?你会把 @volatile
应用于一个函数吗?
根据您要实现的目标,最简单的可能是旧的 synchronized
:
//your mutable state
private var x = 0
//better than locking on 'this' is to have a dedicated lock
private val lock = new Object
def add(i:Int) = lock.synchronized { x += i }
这是 'old Java' 方式,但它可能适合您,具体取决于您正在做什么。当然,这是最快的死锁方法如果您的同步操作更复杂and/or您需要高吞吐量。
这取决于你想在这里保护什么样的共享状态:
最简单和通用的选择是使用旧的 synchronized
。然而,与 Akka 不同的是,它是完全阻塞的,因此可能很容易破坏你的性能,当然还有代码风格,因为它很难控制混乱的副作用。它还可能允许 dead-locks。
Java的locks是相同的方法,但性能可能更好一些。
另一个选项与旧 Java 的 AtomicReference
(实现 CAS 操作)和相关 类 相同。积极的一面是它们是非阻塞的——开发人员实际上使用它们来构建高性能的集合。介绍了锁和CAS的使用方法here。它们都是非常低级的机制,所以我不建议过多使用它们,尤其是对于业务逻辑(任何参与者的实现都会更好)。
如果你的共享状态是一个集合——你可能想使用旧的 Java 的并发集合(它们有像 putIfAbscent
这样的原子操作)。 Scala 有有趣的非阻塞 TrieMap 例如。
Scala STM也是备选
最后,this question专用于轻量级actor模型实现。
P.S。易失性注解只不过是来自 Java 的 volatile
关键字模拟。你可以把它放在方法上,因为任何注释都可以放在任何东西上。
我目前使用 Akka actor 来建立一个以线程安全方式原子执行的代码块(Akka 邮箱语义通过一次处理一条消息来强加原子性)。
然而,这引入了对 actor 系统的需求,以及额外的副作用或膨胀(必须手动将异常传播给调用者,在 ask
上失去类型安全,并且通常使用消息语义而不是函数调用)。
线程安全的原子代码块能否在scala中以更简单的方式实现?你会把 @volatile
应用于一个函数吗?
根据您要实现的目标,最简单的可能是旧的 synchronized
:
//your mutable state
private var x = 0
//better than locking on 'this' is to have a dedicated lock
private val lock = new Object
def add(i:Int) = lock.synchronized { x += i }
这是 'old Java' 方式,但它可能适合您,具体取决于您正在做什么。当然,这是最快的死锁方法如果您的同步操作更复杂and/or您需要高吞吐量。
这取决于你想在这里保护什么样的共享状态:
最简单和通用的选择是使用旧的
synchronized
。然而,与 Akka 不同的是,它是完全阻塞的,因此可能很容易破坏你的性能,当然还有代码风格,因为它很难控制混乱的副作用。它还可能允许 dead-locks。Java的locks是相同的方法,但性能可能更好一些。
另一个选项与旧 Java 的
AtomicReference
(实现 CAS 操作)和相关 类 相同。积极的一面是它们是非阻塞的——开发人员实际上使用它们来构建高性能的集合。介绍了锁和CAS的使用方法here。它们都是非常低级的机制,所以我不建议过多使用它们,尤其是对于业务逻辑(任何参与者的实现都会更好)。如果你的共享状态是一个集合——你可能想使用旧的 Java 的并发集合(它们有像
putIfAbscent
这样的原子操作)。 Scala 有有趣的非阻塞 TrieMap 例如。Scala STM也是备选
最后,this question专用于轻量级actor模型实现。
P.S。易失性注解只不过是来自 Java 的 volatile
关键字模拟。你可以把它放在方法上,因为任何注释都可以放在任何东西上。