3

atom 和 refs 实际有何不同?

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

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

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

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

4

2 回答 2

8

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

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

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

于 2013-08-09T15:55:04.773 回答
1

请记住:

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

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

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

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

于 2013-08-09T15:51:33.743 回答