Kev*_*vin 3 concurrency clojure stm
原子和参考实际上有何不同?
我理解原子声明不同,并通过swap!函数更新,而refs alter在一个内部使用dosync.然而,内部实现看起来非常相似,这让我想知道为什么我会使用一个而不是另一个.
例如,atom的doc页面(http://clojure.org/atoms)指出:
在内部,交换!读取当前值,将函数应用于它,并尝试对其进行比较和设置.由于另一个线程可能在中间时间内更改了值,因此可能必须重试,并在旋转循环中执行此操作.实际效果是该值始终是将所提供的函数应用于当前值的结果.但是,因为函数可能被多次调用,所以它必须没有副作用.
所描述的方法听起来与我用于refs的STM非常相似.
不同之处在于您无法协调多个原子之间的变化,但您可以协调多个参考之间的变化.
参考更改必须在dosync块内进行.dosync中的所有更改都会发生,或者它们都不会发生(原子),但会扩展到该dosync中refs的所有更改.这与数据库事务非常相似.
例如,假设您要从一个集合中删除一个项目并将其添加到另一个集合中,但没有任何人看到任何集合都没有该项目的情况.这是不可能用原子保证的,但你可以用refs保证它.