我想知道 Clojure 是否有针对 ABA 问题的内置解决方案。我正在创建一个显示此问题的示例,但 Clojure 以某种方式检测到更改。这是因为 Clojure 的事务比较的是引用而不是值吗?
我的例子:
(def x (ref 42))
(def io (atom false))
(def tries (atom 0))
(def t1 (Thread. (fn [] (dosync (commute x - 42)))))
(def t2 (Thread. (fn [] (dosync
(Thread/sleep 100)
(commute x + 42)))))
(def t3 (Thread.
(fn []
(dosync
(do
(Thread/sleep 1000)
(swap! tries inc)
(if (= 42 @x)
(reset! io true)))))))
(.start t3)
(.start t1)
(.start t2)
(.join t1)
@x
(.join t2)
@x
(.join t3)
@tries
(if (= true @io) (println "The answer is " @x))
Try 计数始终为 2,因此事务 t3 一定注意到了 t1 和 t2 的 ref 变化。有人知道这种行为的原因吗?