【问题标题】:Clojure reset(ing) multiple atoms at onceClojure 一次重置(ing)多个原子
【发布时间】:2015-08-20 16:40:37
【问题描述】:

假设 foo 和 bar 是原子。

; consistent.
(reset! foo x)
; inconsistent x and y combination.
(reset! bar y)
; consistent.

是否可以一次重置它们以使其他线程无法看到这种不一致?或者是否有必要将 x 和 y 捆绑成一个原子,而不是让 x 和 y 本身就是原子?

【问题讨论】:

    标签: concurrency clojure thread-safety


    【解决方案1】:

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

     (def foo (ref :x))
     (def bar (ref :y))
     (dosync
        (ref-set foo :x1)
        (ref-set bar :y1))
    

    在此示例中,如果任一 ref 被另一个线程中的事务修改,则事务(由 dosync 描述)将被重试,以确保其他线程看到 foobar 的一致视图。

    使用 STM 存在开销,因此选择使用协调的 ref 还是使用封装所有可变状态的单个 atom 将取决于您的具体用法。

    【讨论】:

      【解决方案2】:

      来自Clojure website's page on atoms(强调添加):

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

      这意味着每个atom是相互独立的,因此一组atoms不能被原子更新。

      您可以将这两个项目合并为一个 atom。但您也可能需要考虑refs,它提供多个项目的事务更新:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-28
        • 2014-05-10
        • 2016-07-16
        • 1970-01-01
        相关资源
        最近更新 更多