As an example, if I have: (def a (atom 5))
and execute these from different threads: T1: (swap! a * 2) T2: (swap! a + 2) it depends on timing which update runs first so you can get either 12 (T1 then T2) or 14 (T2 then T1). But it must be one of those results. With a volatile, the reads and writes can interleave in a variety of ways (I think this is all of them as the JMM will guarantee that the read happens-before the write for each T): T1 read, T1 write, T2 read, T2 write: v = 12 T1 read, T2 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) T1 read, T2 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T2 write, T1 read, T1 write: v = 14 T2 read, T1 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T1 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) Non-atomic updates are fine if you have thread isolation though, as there is no chance for interleaving as above. The atomicity you get from atoms must be provided as a consequence of program construction in that case. There are a very small set of cases where non-atomic multi-threaded updates as above are actually valid. [The racy single-check idiom used for hash caching is one - that's a special case where the update function and initial value are identical so threads race to produce the *same* value, and all interleavings produce the same result. This technique used in several places in Clojure for hash caching.] Also note that the default in Java (non-volatile, non-synchronized fields) is even worse than this - they provide neither visibility nor atomicity, so different threads may not even seen writes by other threads at all (not to mention things like long-tearing). On Wednesday, September 10, 2014 9:19:33 AM UTC-5, Alex Miller wrote: > > Usually that's called "visibility". > > Atoms are *not* subject to race conditions if swap! is called from > multiple threads (the state of the atom will not change while the update > function is being applied). The atom is thus "safe" to be used from > multiple threads. > > Volatiles *are* subject to race conditions with vswap! is called from > multiple threads (the state of the volatile may change while the update > function is being applied). The volatile is thus "dangerous" and safety is > derived from how it's used. > > On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: >> >> When I say synchronization, I specifically mean "writes are guaranteed to >> be seen by subsequent reads on any thread*" *as Alex said. >> >> On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: >>> >>> So to summarize, Clojure's volatile provides synchronization across >>> threads but does not provide atomaticity with vswap!. So, as a follow up >>> question, then why would the creation of a volatile be "dangerous" but >>> creating an atom isn't? (Hence the exclamation point in the name >>> "volatile!") >>> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.