In Chapter 2, Concurrency on the JVM and the Java Memory Model, we learned that memory writes do not happen immediately unless proper synchronization is applied. A set of memory writes is not executed at once, that is, atomically. We saw that visibility is ensured by the happens-before relationship, and we relied on the
synchronized statement to achieve it. Volatile fields were a more lightweight way of ensuring happens-before relationships but a less powerful synchronization construct. Recall how volatile fields alone could not implement the
getUniqueId method correctly.
In this section, we study atomic variables that provide basic support for executing multiple memory reads and writes at once. Atomic variables are volatile variables' close cousins but are more expressive than volatile variables; they are used to build complex concurrent operations without relying on the