Java provides a set of useful classes in it’s java.util.concurrent.atomic package. This package contains a small toolkit of classes that support lock-free (at least whenever possible) and thread-safe programming on single variables. But how can it be lock-free (or what does that mean)? How useful they are? When to use them?
The Java atomic package gives us a set of useful classes. They are a result of an effort to provide developers a set of atomic features for the most common race condition scenarios (check-then-act and read-modify-write). The JVM will try to enforce atomicity of such operations but it depends on the CPU features. By atomic operations I mean lock-free, however, in some CPUs it is still impossible to provide such features (atomicity depends on CPUs providing such features), however the JVM will still provide you a virtual atomic operation (a bit slower than atomic operations).
This atomic operations allows one to avoid synchronized blocks. They also guarantee the memory visibility (like volatil variables), that is, accesses (read/write) are done against the main memory.
The memory effects for accesses and updates of atomics generally follow the rules for volatiles, as stated in section 17.4 of The Java™ Language Specification.
gethas the memory effects of reading a
sethas the memory effects of writing (assigning) a
lazySethas the memory effects of writing (assigning) a
volatilevariable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-
volatilewrites. Among other usage contexts,
lazySetmay apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.
weakCompareAndSetatomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the
compareAndSetand all other read-and-update operations such as
getAndIncrementhave the memory effects of both reading and writing
So, from what was said before, we can say that Atomic classes are a good optimisation in terms of process management (no locking) but then they have the requirement of changing the main memory directly. In some scenarios this class is really useful, however not all scenarios are good. Usually, in enterprise applications the time it takes to write to main memory on each computation is expensive when comparing to the memory block flush of synchronized blocks.
Use it with wisely, have in consideration all that has been said. If your computation is only about few variables as your state, Atomic classes are really a good option.
© 2019 Joao Melo's Blog | Theme by Eleven Themes