对于读者来说,拥有自己的时间表意味着什么

时间:2013-09-21 23:16:20

标签: clojure

在他的演讲are we there yet中,在57:25,Rich Hickey谈到了多元并发控制。列出的优点之一是读者有自己的时间表的能力。我很好奇这在实践中意味着什么。这是通过简单地让读者保存观察值的历史来完成的吗?或者它是以某种方式在clojure的STM的帮助下完成的?很高兴看到一个如何在clojure中使用它的例子。

1 个答案:

答案 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
---------------------------------

工作原理:

  1. 将计数器变量声明为ref(事务变量类型)并将其初始值设置为0

  2. 使用匿名函数创建Java线程,该函数通过在循环中递增计数器来更改计数器并“.start”该线程。

  3. 以两步方式读取计数器,相隔1 ms延迟并打印每个值。正如您所看到的,两个值都是预期的不同。当两个观察同一对象的对象接收到不同的数据时,这会模拟单独的时间线。

  4. 与上述相同,但在世界快照中。放置睡眠功能不会影响输出值。两者都是平等的。