Card 07/ 09

ComparisonDifficulty: Advanced1 min

volatile vs synchronized vs Atomic Classes

Two problems, three tools, and a rule based on how many variables must change together.

Java has three everyday tools for shared state: volatile, synchronized, and the atomic classes such as AtomicInteger. All three make writes visible to other threads; they differ in what they make atomic and in what they cost. Picking by name recognition is how a volatile counter reaches production still losing updates.

What each tool provides, and what it costs
ToolMakes writes visibleMakes an operation atomicCosts
volatileYesNoAlmost nothing
synchronizedYesYes, for the whole blockA lock; other threads wait
AtomicInteger and friendsYesYes, for one variableVery little; no waiting
java
volatile boolean stopped;                     // a flag one thread writes and others read

synchronized void transfer(long pence) { }    // several fields changed together

AtomicLong total = new AtomicLong();          // one value, incremented from many threads
total.incrementAndGet();

The decision rule. One field that is only ever read and written whole: volatile. One value that is read, computed from and written back: an atomic class. Two or more fields that have to change together: synchronized, because nothing else covers more than one variable.

The atomic classes, such as AtomicLong, work with a compare-and-set loop: read the value, compute the new one, and swap it in only if nothing changed in between, trying again if something did. No thread ever waits, which is why they beat a lock for a single counter, and why they cannot replace one for the money transfer.