Start here. This is the direct spoken answer to practice first.
Overview
Thread safety is a property of the complete state transition and access protocol, not of one field keyword.
A race condition occurs when correctness depends on the timing or interleaving of concurrent operations. counter++ is a read, calculation, and write, so two threads can lose an update even if individual integer reads and writes are atomic. Thread-safe code preserves its invariants under concurrent access. Common strategies are thread confinement, immutable state, synchronization around a compound action, atomic variables, or concurrent collections.