1

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

4

1 回答 1

1

我认为 Rich 的意思是交易之外的读者在每次尝试读取值时都会看到处于当前状态的世界,而这种世界观对他们每个人来说都是个人的。

当您有两个不相关的函数(未绑定在同一事务中)试图获取变量(原子、引用、代理等)的当前值时,不能保证它们获得(查看)相同的值。

例子:

(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. 与上面相同,但在世界快照中。设置睡眠功能不会影响输出值。他们两个是平等的。

于 2013-10-14T22:20:57.453 回答