Clojure的功能应该交换!适用于幂等?

ond*_*sek 6 swap clojure

我正在通过Clojure Koans,我现在正在玩原子.我的问题与Koans无关,但与普通人有关.

考虑Koans的以下(缩短)示例:

(def atomic-clock (atom 0))

(meditations
    (= 1 (do
        (swap! atomic-clock inc)
            @atomic-clock)))
Run Code Online (Sandbox Code Playgroud)

交换文档!声明它应用的函数(inc在这种情况下)可以被多次调用,因此该函数应该没有副作用.

显然,inc没有副作用,但不是幂等的.这是否意味着,上述断言实际上可能仍然失败?即,在确实多次调用函数的情况下,原子的值增加了不止一次?

Mic*_*zyk 8

swap!如果有多个线程竞争修改Atom ,则可以多次调用传递给的函数.然而,只要它没有副作用,只有最终调用的返回才会反映在Atom的因果历史中.1

这是一种可能的情况:

  1. 线程1尝试(swap! atomic-clock inc).

  2. 线程2尝试相同.

  3. 线程2设法执行它的swap!第一个.

  4. 线程1尝试对原子进行比较和交换并失败,因为它的原始值的概念现在已过时.

  5. 线程1重试并成功提交.

这里有三个调用inc,两个在线程1上,一个在线程2上.

inc不是幂等的事实不是问题.


1抽象地考虑; Clojure实际上并不存储Atoms的历史信息.