我还找到了解决我特定问题的方法。如果有必要考虑支持有效用例的话,我会将其修改为通用问题陈述。
所以,基本问题与 swap! 解决冲突的方式有关。我用以下代码演示了这一点
(def d (atom 0))
(pmap (fn [_] (swap! d (fn [x] (println "x:" x) (inc x)))) (range 10))
x: 0
0x: 0
x: x: 0
0
0x: x:x: 0
0
x: 1
2x
0
1
2x
x: x: 3
2x
4x: x: 24x
2
x: x: 5 2
5
5
1
6
2x
7
1
7
2
8
76x
=> (1 10 2 9 4 3 6 5 8 7)
最终结果是正确的(增加了10个值),但是为了得到这个结果,交换函数被调用超过30次,且存在许多内部状态的重复(例如,“0”)。我可以推测,在内部,swap! 在并行运行函数时,当发生冲突时会重新播放一些。
如果我们把这个问题转换到缓存中,有一些情况下,c/通过缓存的并行实例see has? = false,因此运行 missed 分支,然后在更新发生冲突时再次运行。
这没有问题,尽管我仍然可能会说,至少文档说明很混乱,也许应该指出这是关于单线程执行的。
我将就一个一般性的问题陈述及其潜在解决方案作出第二条评论。