Thread-Safe Classes in Java
Fast recall
Quick revision
Core answer
Understanding of thread safety as a design property — not just a technical term
Thinking all Java classes are thread-safe by default — ArrayList and HashMap are not
Give examples of thread-safe vs non-thread-safe classes and the mechanism that makes each safe
Interview-ready guide
Interview answer
A thread-safe class is one that works correctly when multiple threads use it at the same time.
It protects its internal state so concurrent operations don't corrupt data or cause unexpected behavior. The classic example is a counter. If two threads both call increment on a non-thread-safe counter at the exact same time, they might both read the value as 5, both calculate 6, and both write 6 back — so you get 6 instead of 7.
That's data corruption. A thread-safe counter uses either synchronized methods or an AtomicInteger to ensure the increment operation is atomic, meaning it completes entirely before another thread can access it. Many mutable Java classes do not promise thread safety; adding it changes their API and coordination costs.
ArrayList and HashMap do not support unsynchronized concurrent mutation as a safe usage pattern. But Java provides thread-safe alternatives: ConcurrentHashMap, CopyOnWriteArrayList, AtomicInteger. When you build a Spring Boot service, this really matters.
If you have an at-Service class with an instance variable like a HashMap that multiple request threads access, you'll get race conditions. You need to either use ConcurrentHashMap, or synchronize access to that map, or redesign so each request has its own data. Thread safety is about making sure shared mutable state is protected.
Thread-Safe Classes in Java
Direct Answer
A thread-safe class preserves its documented invariants when used concurrently according to its API contract. It may use immutability, confinement, locks, atomic variables, or concurrent data structures. Individual thread-safe methods do not automatically make a multi-call workflow atomic; callers must follow any documented compound-operation rules.
Common Mistakes & Pitfalls
- Calling a class thread-safe without defining operations: safety is about documented behavior and invariants under concurrency.
- Assuming a concurrent collection protects surrounding logic: a separate check followed by update may still race.
- Synchronizing every method blindly: identify the shared state and invariant first.
- Publishing mutable state unsafely: construction and later access both need a sound visibility protocol.
- Promising corruption on every concurrent write: unsynchronized access is invalid for the required behavior, but the exact symptom is not deterministic.
Check your understanding
Answer these without looking back at the article.
- Why is String thread-safe in Java?
- What is the difference between HashMap and ConcurrentHashMap?
- What does stateless mean for Spring beans?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.