The root of data races
A data race needs two ingredients: shared state and at least one writer. If a value never changes after it is built, every thread sees the same bytes forever. Remove the writer and the race cannot exist.
What immutability buys you
- No locks for reads. Many threads can read a frozen value at once with zero coordination.
- Safe publication. Once you hand out an immutable object, you can never corrupt a reader by mutating it later.
- Easy reasoning. A function that only takes immutable inputs always returns the same answer for the same arguments.
Updating without mutating
You do not lose the ability to change things. Instead of editing in place, you build a new value and swap a single reference. The old value stays valid for anyone still reading it. This is how functional languages model state: a chain of versions rather than one mutable cell.
The cost
Copying can be wasteful, which is why real systems use persistent data structures that share unchanged parts between versions.
Key idea
Immutable data has no writers after construction, so concurrent readers need no locks and races become impossible.