【问题标题】:how do atoms differ from refs?原子与参考有何不同?
【发布时间】:2013-08-09 15:41:22
【问题描述】:

atoms 和 refs 实际有何不同?

我知道原子的声明方式不同,并通过swap! 函数更新,而引用在dosync 中使用alter然而,内部实现似乎非常相似,这让我想知道为什么我会使用一个而不是另一个。

例如,atoms 的文档页面 (http://clojure.org/atoms) 指出:

在内部,交换!读取当前值,将函数应用于它,并尝试比较并设置它。由于另一个线程可能在中间时间更改了该值,它可能必须重试,并在自旋循环中这样做。最终效果是该值将始终是原子地将提供的函数应用于当前值的结果。但是,由于该函数可能会被多次调用,所以它必须没有副作用。

所描述的方法听起来与我用于参考的 STM 非常相似。

【问题讨论】:

  • 既然您选择了答案,请告诉我们它是如何回答您的问题的?
  • 和你的一样。我必须选择一个答案,而且我更喜欢那个答案。你的还不错。

标签: concurrency clojure stm


【解决方案1】:

不同之处在于你不能协调多个原子之间的变化,但你可以协调多个参考之间的变化。

引用更改必须在 dosync 块内进行。 dosync 中的所有更改都发生或没有发生(原子),但这会扩展到该 dosync 中的 refs 的 所有 更改。这很像数据库事务。

例如,假设您想从一个集合中删除一个项目并将其添加到另一个集合,但没有人看到两个集合都没有该项目的情况。这是不可能用 atom 保证的,但你可以用 refs 保证。

【讨论】:

    【解决方案2】:

    请记住:

    • 使用 Refs 进行同步、协调和共享的更改。
    • 使用 Atom 进行同步、独立和共享的更改。

    对我来说,我不关心 atom 和 refs 之间的实现差异。我关心的是他们每个人的“用例”

    我使用 refs 我需要更改多个引用类型的状态并且我需要 ATM 语义。当我改变一种引用类型(对象,取决于你如何看待它)的状态时,我会使用原子。

    例如,如果我需要增加网络分析系统中的页面点击次数;我使用原子。如果我需要在两个账户之间转账,我会使用 refs。

    【讨论】:

    • 我同意我不应该关心实现,只关心用例,但是文档已经超出了描述实现的方式,这听起来与 STM 非常相似。
    • 另外,如果我只需要一个 AtomicLong 我不认为我会使用原子。
    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 2012-10-27
    • 2020-02-19
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 2012-05-17
    • 2011-01-10
    相关资源
    最近更新 更多