class Concurrent::Atom

Atoms provide a way to manage shared, synchronous, independent state.

An atom is initialized with an initial value and an optional validation proc. At any time the value of the atom can be synchronously and safely changed. If a validator is given at construction then any new value will be checked against the validator and will be rejected if the validator returns false or raises an exception.

There are two ways to change the value of an atom: {#compare_and_set} and {#swap}. The former will set the new value if and only if it validates and the current value matches the new value. The latter will atomically set the new value to the result of running the given block if and only if that value validates.

## Example

“‘ def next_fibonacci(set = nil)

return [0, 1] if set.nil?
set + [set[-2..-1].reduce{|sum,x| sum + x }]

end

# create an atom with an initial value atom = Concurrent::Atom.new(next_fibonacci)

# send a few update requests 5.times do

atom.swap{|set| next_fibonacci(set) }

end

# get the current value atom.value #=> [0, 1, 1, 2, 3, 5, 8] “‘

## Observation

Atoms support observers through the {Concurrent::Observable} mixin module. Notification of observers occurs every time the value of the Atom changes. When notified the observer will receive three arguments: ‘time`, `old_value`, and `new_value`. The `time` argument is the time at which the value change occurred. The `old_value` is the value of the Atom when the change began The `new_value` is the value to which the Atom was set when the change completed. Note that `old_value` and `new_value` may be the same. This is not an error. It simply means that the change operation returned the same value.

Unlike in Clojure, ‘Atom` cannot participate in {Concurrent::TVar} transactions.

@!macro thread_safe_variable_comparison

@see clojure.org/atoms Clojure Atoms @see clojure.org/state Values and Change - Clojure’s approach to Identity and State