Java's threading model is based on three fundamental concepts:
Shared, visible-by-default mutable state
This means that objects are easily shared between different threads in a process,
and that they can be changed (“mutated”) by any thread holding a reference to
Preemptive thread scheduling
The OS thread scheduler can swap threads on and off cores at more or less any
Object state can only be protected by locks
Locks can be hard to use correctly, and state is quite vulnerable—even in unex‐
pected places such as read operations.
Taken together, these three aspects of Java's approach to concurrency explain why
multithreaded programming can cause so many headaches for developers.