On Jun 18, 9:35 pm, Rich Hickey <[email protected]> wrote:
> http://clojure.org/refs
>
> point #8:
>
> "If a constraint on the validity of a value of a Ref that is being  
> changed depends upon the simultaneous value of a Ref that is not being  
> changed, that second Ref can be protected from modification by calling  
> ensure. Refs 'ensured' this way will be protected (item #3), but don't  
> change the world (item #2)."
>
> That describes your situation, and you can use 'ensure' to ensure the  
> serializability of your reads.

Thanks, that was all very helpful. With ensure, there's no write skew.


> This is better than the "dummy write"  
> solution in that multiple ensures of the same refs don't conflict.

I haven't been able to verify this part - are you refering to
Clojure's current implementation? In my experiment below using Clojure
1.0.0, I'm seeing conflicts.


No conflict when we use deref:-

(def a (ref 0))
(def b (ref 0))
(def c (ref 0))

(.start
  (Thread.
    #(dosync
      (println "Reading a to update b")
      (let [old-a (deref a)]
        (Thread/sleep 2000)
        (println "Updating b")
        (ref-set b (inc old-a))))))

(.start
  (Thread.
    #(dosync
      (println "Reading a to update c")
      (let [old-a (deref a)]
        (Thread/sleep 2000)
        (println "Updating c")
        (ref-set c (inc old-a))))))

(Thread/sleep 3000)
(dosync
  (println "a=" @a ", b=" @b ", c=" @c))

(Thread/sleep 3000)
(dosync
  (println "a=" @a ", b=" @b ", c=" @c))



Reading a to update b

Reading a to update c

Updating b

Updating c

a= 0 , b= 1 , c= 1

a= 0 , b= 1 , c= 1

(all output as expected)



Conflict when we use ensure:-

Replace each
      (let [old-a (deref a)]
with
      (let [old-a (ensure a)]



Reading a to update b

Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c
Reading a to update c

Updating b

Reading a to update c

a= 0 , b= 1 , c= 0

Updating c

a= 0 , b= 1 , c= 1


(I expected the same output as for deref, because a is never updated.)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to