Concurrency 在以下Clojure代码中,alter可以替换为通勤吗?
这段代码来自《活的克洛尤尔》。在书中,作者还举了一个例子,用通勤代替改变。我想知道一开始的Concurrency 在以下Clojure代码中,alter可以替换为通勤吗?,concurrency,clojure,Concurrency,Clojure,这段代码来自《活的克洛尤尔》。在书中,作者还举了一个例子,用通勤代替改变。我想知道一开始的pos?测试,我们真的可以做这个替换吗?不,当减少右手咬伤时,用通勤替换是不正确的 条件句的目的显然是防止右手咬伤变成负数。减量仅在假定右侧咬合在交易结束前不会改变的情况下有效。虽然与alter一样,communion有自己的ref世界快照视图,但它将在提交时重新读取并将communion函数重新应用于ref,这在本程序中是错误的 因此,使用通勤可以将负值提交给右手咬伤 要么坚持使用alter,要么使用而不
pos?
测试,我们真的可以做这个替换吗?不,当减少右手咬伤时,用通勤
替换是不正确的
条件句的目的显然是防止右手咬伤
变成负数。减量仅在假定右侧咬合
在交易结束前不会改变的情况下有效。虽然与alter
一样,communion
有自己的ref世界快照视图,但它将在提交时重新读取并将communion函数重新应用于ref,这在本程序中是错误的
因此,使用通勤
可以将负值提交给右手咬伤
要么坚持使用alter
,要么使用而不是@
(尽管这使整个通勤练习变得毫无意义)。有趣的小事实:不仅确保
在这一点旁边,它还容易发生(灾难性的)活锁,而且我可以使用您的代码片段轻松地重现这一点。看。我认为这是否重要归结于条件(当(pos?@右手咬伤)
中的读取。右侧咬伤的deref
不在communion
内,在提交前应遵守快照一致性。因此,如果条件在读取过程中看到正面的右侧咬合
,则应保证在提交之前具有一致的值。如果条件在通勤时间内,则会发生变化。@A.Webb Ref reads无法在提交时检测到修改–为此,您需要确保。这也是问题的症结所在:comment
在提交期间(=仍在事务中!)重新读取ref的当前值(快照之外的值!),然后无条件地重新应用comment函数。这就是它变成一个检查然后行动的错误。在REPL中自己尝试一下,这不太难验证。
(def alice-height
(ref 3))
(def right-hand-bites
(ref 10))
(defn eat-from-right-hand []
(dosync
(when (pos? @right-hand-bites)
(alter right-hand-bites dec)
(alter alice-height #(+ % 24)))))