在他的演讲are we there yet中,在57:25,Rich Hickey谈到了多元并发控制。列出的优点之一是读者有自己的时间表的能力。我很好奇这在实践中意味着什么。这是通过简单地让读者保存观察值的历史来完成的吗?或者它是以某种方式在clojure的STM的帮助下完成的?很高兴看到一个如何在clojure中使用它的例子。
答案 0 :(得分:1)
我认为Rich意味着交易之外的读者每次尝试阅读价值时都会看到世界,因为它处于当前状态,而这个世界观对每个人来说都是个体的。
当你有两个不相关的函数(没有在同一个事务中绑定)试图获取变量的当前值(atom,ref,agent等)时,他们不能保证获得(参见)相同的价值。
示例:
(let [
; 1.
counter (ref 0)
; 2.
_ (.start (Thread. (fn [] (while (< @counter 1000000)
(dosync (alter counter inc))))))
_ (Thread/sleep 10)
; 3.
_ (let [r1 @counter
_ (Thread/sleep 1)
r2 @counter]
(println "free reader 1: " r1 "free reader 2:" r2))
; 4.
_ (dosync (let [r1 @counter
_ (Thread/sleep 1)
r2 @counter]
(println "frozen reader 1: " r1 "frozen reader 2:" r2)))
_ (println "---------------------------------")])
示例输出:
free reader 1: 30573 free reader 2: 31295
snapshot reader 1: 105498 snapshot reader 2: 105498
---------------------------------
free reader 1: 37567 free reader 2: 38369
snapshot reader 1: 181392 snapshot reader 2: 181392
---------------------------------
free reader 1: 37317 free reader 2: 88570
frozen reader 1: 467471 frozen reader 2: 467471
---------------------------------
工作原理:
将计数器变量声明为ref(事务变量类型)并将其初始值设置为0
使用匿名函数创建Java线程,该函数通过在循环中递增计数器来更改计数器并“.start”该线程。
以两步方式读取计数器,相隔1 ms延迟并打印每个值。正如您所看到的,两个值都是预期的不同。当两个观察同一对象的对象接收到不同的数据时,这会模拟单独的时间线。
与上述相同,但在世界快照中。放置睡眠功能不会影响输出值。两者都是平等的。