multi threading
intermediatesynchronized vs volatile
Pick the minimal tool — mutual exclusion (synchronized) vs visibility-only (volatile) — for the concurrency problem you actually have.
Concurrency bugs come in two flavours — visibility (one thread doesn't see another's write) and atomicity (a compound action is interrupted partway) — and synchronized and volatile address different combinations of them. Choosing the minimal correct tool is both a performance question and a correctness one.
volatile = posting an update on a public board (everyone sees the latest, but two people can still post conflicting updates). synchronized = the single key to a room (only one person inside, others wait).
Key Concepts
1
volatile guarantees visibility and ordering but not atomicity. Marking a field volatile forces reads and writes to go to main memory rather than a per-thread cache, so once one thread writes, every other thread sees the new value immediately, and it establishes a happens-before relationship that prevents certain instruction reorderings. What it does not do is make compound operations atomic: count++ is a read-modify-write, and two threads can both read the same value before either writes, losing an update even on a volatile field. synchronized provides both atomicity and visibility: it acquires a monitor lock so only one thread executes the guarded region at a time, and entering and exiting the monitor also flushes and reloads memory, so it subsumes volatile's visibility guarantee.
volatilecount++synchronized
2
The rule of thumb is to use volatile for a simple flag or a reference that is written by one thread and read by others — a running boolean that stops a loop, or the doubly-checked-locking instance field — where no read-modify-write is involved. Use synchronized (or a Lock, or an atomic class like AtomicInteger) whenever multiple steps must happen indivisibly or several fields must stay mutually consistent. For a lock-free counter, AtomicInteger's compare-and-swap is often the best of both worlds, giving atomicity without blocking.
volatilerunningsynchronizedLockAtomicInteger