Concurrency 原子与参考原子有何不同?
原子和参照物的实际区别是什么 我知道原子的声明不同,并通过Concurrency 原子与参考原子有何不同?,concurrency,clojure,stm,Concurrency,Clojure,Stm,原子和参照物的实际区别是什么 我知道原子的声明不同,并通过交换进行更新函数,而refs在dosync中使用alter然而,内部实现似乎非常相似,这让我想知道为什么我会使用其中一个而不是另一个。 例如,atoms()的文档页面说明: 内部,交换!读取当前值,将函数应用于该值,并尝试进行比较和设置。由于另一个线程可能在中间时间更改了值,因此它可能必须重试,并在旋转循环中重试。净效果是,该值将始终是原子地将提供的函数应用于当前值的结果。但是,由于该函数可能被多次调用,因此它必须没有副作用 所描述的方法
交换进行更新
函数,而refs在dosync
中使用alter
然而,内部实现似乎非常相似,这让我想知道为什么我会使用其中一个而不是另一个。
例如,atoms()的文档页面说明:
内部,交换!读取当前值,将函数应用于该值,并尝试进行比较和设置。由于另一个线程可能在中间时间更改了值,因此它可能必须重试,并在旋转循环中重试。净效果是,该值将始终是原子地将提供的函数应用于当前值的结果。但是,由于该函数可能被多次调用,因此它必须没有副作用
所描述的方法听起来与我用于REF的STM非常相似。请记住:
- 使用参照进行同步、协调和共享更改
- 使用原子进行同步、独立和共享更改
例如,如果我需要增加网页分析系统中的页面点击次数;我使用原子。如果我需要在两个账户之间转账,我会使用ref。区别在于你不能协调多个原子之间的变化,但你可以协调多个ref之间的变化 Ref更改必须在
dosync
块内进行。dosync中的所有更改都会发生,或者都不会发生(原子),但这会扩展到该dosync中对ref的所有更改。这与数据库事务的行为非常相似
例如,假设您想从一个集合中删除一个项并将其添加到另一个集合中,但没有人看到两个集合都没有该项的情况。原子无法保证这一点,但你可以用参考文献来保证这一点。我同意我不应该关心实现,只关心用例,但文档对实现进行了详细描述,这听起来与STM非常相似。此外,如果我只需要一个原子,我想我不会用原子。既然你选择了一个答案,你能告诉我们它是如何回答你的问题的吗?就像你的答案一样。我不得不选择一个答案,我更喜欢那个答案。你的还不错。