AtomicInteger vs synchronized in Java
Fast recall
Quick revision
Core answer
AtomicInteger provides atomic operations such as incrementAndGet() and compareAndSet() with volatile-style visibility for its value. Its implementation commonly uses compare-and-set and may retry under contention. It is often a good fit for one independent counter, but it is not guaranteed faster than synchronized and cannot by itself protect an invariant across several values.Awareness of modern concurrency utilities beyond the basic synchronized keyword—java.util.concurrent is essential for production Java.
Not knowing AtomicInteger exists, or thinking it's just a wrapper around synchronized when it actually uses fundamentally different lock-free algorithms.
Explain the non-blocking nature of CAS (compare-and-swap) and why it scales better under high contention—failed CAS operations retry immediately without blocking the thread.
Interview-ready guide
Interview answer
AtomicInteger gives me atomic operations on one integer, so incrementAndGet() is safe where counter++ is not. Its implementation normally uses compare-and-set: update only if the value still matches what was read, otherwise retry.
That can avoid monitor blocking for a small independent value, but I would not promise it is always faster than synchronized; under heavy contention, retries also cost time. More importantly, it protects only that atomic operation. If I must debit one account and credit another as one invariant, two separate atomic integers are not enough. I would use a lock, a transaction, or a design that represents the compound change atomically.
AtomicInteger vs synchronized in Java
Direct Answer
AtomicInteger provides atomic operations such as incrementAndGet() and compareAndSet() with volatile-style visibility for its value. Its implementation commonly uses compare-and-set and may retry under contention. It is often a good fit for one independent counter, but it is not guaranteed faster than synchronized and cannot by itself protect an invariant across several values.
Common Mistakes & Pitfalls
- Using AtomicInteger for compound operations: Freshers call get then set thinking it's atomic, but get followed by set is two operations—another thread can change the value between them. Use compareAndSet or updateAndGet for atomic compound operations.
- Not understanding CAS retry loops: The incrementAndGet method internally uses a loop with compareAndSet—if contention is extremely high, it can spin many times, though it's still faster than blocking.
- Mixing AtomicInteger with synchronized: If some code uses atomic operations and other code uses synchronized on a different lock to access the same logical state, you still have race conditions—pick one concurrency strategy and stick to it.
- Assuming all atomic class methods are lock-free: Some methods like lazySet have weaker guarantees—read the javadoc to understand memory visibility semantics.
Check your understanding
Answer these without looking back at the article.
- What is compare-and-swap (CAS)?
- What are the other Atomic classes in Java?
- When would synchronized be better than AtomicInteger?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.