Card 08/ 09
Practice: Choosing volatile, an Atomic Class or a Lock for Each Field
A flag, a counter, a shared map and two fields that must agree.
volatile fixes visibility, an atomic class makes one value's read-compute-write atomic, and a lock covers several fields at once. For each field below, decide what it needs (nothing, volatile, an atomic class, or a lock) and why, all four before you open the answer.
| The field and how it is used | |
|---|---|
| 1 | boolean shutdown, written once by a signal handler and read by every worker loop |
| 2 | long requestsHandled, incremented by every request thread |
| 3 | final Map<String, Session> sessions, put into and read by many threads |
| 4 | long balance and long lastMovement, which must always agree with each other |
What each of the four needs
| Needs | Why | |
|---|---|---|
| 1 | volatile | Written whole, never computed from itself, so visibility is the only problem |
| 2 | An AtomicLong | Read, add, write back: volatile would make it visible and still lose updates |
| 3 | A ConcurrentHashMap | final publishes the reference safely; the map's contents still need a thread-safe implementation |
| 4 | A lock, held across both writes | Two fields that must agree, which no per-field tool can span |
The third is the one to pause on. final guarantees that every thread sees the reference once the constructor finishes, and says nothing about what happens inside the object it points at.
The fourth marks the limit of the other tools. An atomic class covers one variable, and once correctness spans two fields the only tool left is a lock.
← → move through sections and cards