Race conditions and clojure atoms

Hi guys: The documentation for the clojure atom says that -

"Changes to atoms are always free of race conditions." 

However, the condition of the race is determined not only from the point of view of change, but, rather, in the context of parallel logical operations in different threads.

I wonder - what is the significance of the guarantee that "Changes in atoms are always free from race conditions"? In java, we have atomic primitives that support certain thread-safe operations that are specific (e.g. AtomicInteger supports the getAndIncrement operation). But clojure atoms are agnostic types, for example, we can call:

  (atom "Hi im a string") Or (atom (.getClass Object)) 

The flexibility of the atomic method means that Clojure, under the hood, does not “intelligently” provide atomic / thread-safe operations for atoms.

Thus, I would ask - what exactly does the atomic method "do" for our objects (i.e. does it just synchronize the entire object?)

+7
source share
1 answer

An atom is a place to store atoms, guaranteed by flow safety.

Atoms are similar to Java kernel data types (such as AtomicReference ), but in reality they are somewhat more powerful, because the atom allows you to use an arbitrary function to update the atom. Example:

 (def a (atom "foo")) (defn appender [x] "Higher order function that returns a function which appends a specific string" (fn [s] (str sx))) (swap! a (appender "bar")) => "foobar" 

In the above example, the swap! Operation behaves atomically, even though the appender operation we pass to it can potentially be a rather complex function. In fact, atoms allow you to use an arbitrary update operation atomically (usually you should stick with pure functions, since it is possible that a function will be called several times in case of competition).

Atoms obviously do not guarantee the safety of the streams of objects that you put in them (for example, if you put an unsynchronized Java ArrayList inside, then it is still unsafe for simultaneous use). However, if you adhere to Clojure immutable data types that are completely thread safe, then you will be good.

+11
source

All Articles