Concurrency Clojure一次重置多个原子

Concurrency Clojure一次重置多个原子,concurrency,clojure,thread-safety,Concurrency,Clojure,Thread Safety,假设foo和bar是原子 ; consistent. (reset! foo x) ; inconsistent x and y combination. (reset! bar y) ; consistent. 是否可以立即重置它们,这样其他线程就看不到这种不一致性?或者是否有必要将x和y捆绑成一个原子,而不是将x和y本身作为原子?来自(重点补充): 原子提供了一种管理共享、同步、独立状态的方法 这意味着每个atom彼此独立,因此一组atoms不能以原子方式更新 您可以将这两个项目组合成一个

假设foo和bar是原子

; consistent.
(reset! foo x)
; inconsistent x and y combination.
(reset! bar y)
; consistent.
是否可以立即重置它们,这样其他线程就看不到这种不一致性?或者是否有必要将x和y捆绑成一个原子,而不是将x和y本身作为原子?

来自(重点补充):

原子提供了一种管理共享、同步、独立状态的方法

这意味着每个
atom
彼此独立,因此一组
atom
s不能以原子方式更新

您可以将这两个项目组合成一个
atom
。但是您也可能需要考虑,它提供了多个项目的事务性更新:

事务引用(REF)确保通过软件事务内存(STM)安全地共享可变存储位置

从(增加强调)开始:

原子提供了一种管理共享、同步、独立状态的方法

这意味着每个
atom
彼此独立,因此一组
atom
s不能以原子方式更新

您可以将这两个项目组合成一个
atom
。但是您也可能需要考虑,它提供了多个项目的事务性更新:

事务引用(REF)确保通过软件事务内存(STM)安全地共享可变存储位置


对于多个引用的协调更新,您希望使用,而不是原子。REF只能在事务内部修改,Clojure的STM(软件事务内存)确保在提交事务之前REF上的所有操作都成功,因此事务之外的所有线程都可以看到REF的一致视图

 (def foo (ref :x))
 (def bar (ref :y))
 (dosync
    (ref-set foo :x1)
    (ref-set bar :y1))
在此示例中,如果另一个线程中的某个事务修改了某个ref,则将重试该事务(由
dosync
描述),以确保其他线程看到
foo
bar
的一致视图


使用STM会有开销,因此选择使用协调引用还是使用封装所有可变状态的单个原子取决于您的确切用法。

对于多个引用的协调更新,您希望使用而不是原子。REF只能在事务内部修改,Clojure的STM(软件事务内存)确保在提交事务之前REF上的所有操作都成功,因此事务之外的所有线程都可以看到REF的一致视图

 (def foo (ref :x))
 (def bar (ref :y))
 (dosync
    (ref-set foo :x1)
    (ref-set bar :y1))
在此示例中,如果另一个线程中的某个事务修改了某个ref,则将重试该事务(由
dosync
描述),以确保其他线程看到
foo
bar
的一致视图

使用STM会有开销,因此选择使用协调引用还是使用封装所有可变状态的单个原子取决于具体的使用情况