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
-~----------~----~----~----~------~----~------~--~---