Start here. This is the direct spoken answer to practice first.
Overview
The decision depends on whether the code publishes one value, updates one atomic variable, or protects a compound invariant.
volatile gives visibility and ordering for reads and writes of one field, but it does not make compound operations such as increment atomic. synchronized provides mutual exclusion plus visibility for all state consistently protected by the same monitor. Atomic classes provide operations such as compare-and-set and increment as indivisible updates on one variable. Choose the mechanism that covers the entire state transition.