AtomicInteger Operations in Java
`AtomicInteger` provides thread-safe operations on a single integer without requiring an explicit lock. It is useful when multiple threads need to update or read shared numeric state safely.
`AtomicInteger` is a class in `java.util.concurrent.atomic` designed for atomic operations on an `int`. Its operations such as `get()`, `set()`, `incrementAndGet()`, and `compareAndSet()` provide thread-safe access to the stored value.
An atomic operation completes as one indivisible action from the perspective of other threads. This matters for compound operations such as incrementing a shared counter: a plain `count++` involves reading, adding, and writing, so two threads can interfere with each other.
`compareAndSet(expected, update)` is a common building block for lock-free algorithms. It changes the value only when the current value equals the expected value, returning `true` when the update succeeds and `false` otherwise.
Atomicity does not make an entire multi-step algorithm automatically thread-safe. If several related variables must change together as one invariant, a lock or another coordination mechanism may still be appropriate.
Key points
- `AtomicInteger` provides atomic access to a shared `int`.
- Use `incrementAndGet()` or `getAndIncrement()` for atomic increments.
- `compareAndSet()` updates the value only if it still equals the expected value.
- Atomic operations avoid explicit locking for supported single-value operations.
- Atomicity of one variable does not automatically make a larger multi-step operation thread-safe.
Interview questions
Why would you use `AtomicInteger` instead of a normal `int` for a shared counter?
A normal `int` does not make a compound update such as incrementing safe when multiple threads access it. `AtomicInteger` provides atomic read-modify-write methods such as `incrementAndGet()`. This prevents lost updates for that operation without requiring an explicit lock.
What does `compareAndSet()` do?
`compareAndSet(expected, update)` checks the current value against `expected` and changes it to `update` only when they match. The operation is atomic, so another thread cannot modify the value between the comparison and update. It returns `true` on success and `false` when the expected value does not match.
Is `volatile int` equivalent to `AtomicInteger`?
No. `volatile` provides visibility of writes between threads, but it does not make compound operations such as increment atomic. `AtomicInteger` provides atomic read-modify-write operations as well as visibility guarantees appropriate to those operations. Therefore, an atomic counter generally needs an atomic class or another synchronization mechanism.
When is `AtomicInteger` not enough to make code thread-safe?
It is not enough when correctness depends on coordinating multiple values or multiple operations as one unit. Each individual atomic operation can be safe while the overall sequence still has a race condition. In those cases, a lock or another coordination mechanism may be needed to preserve the required invariant.
What is the difference between `compareAndSet()` and unconditional `set()`?
`set()` writes the supplied value regardless of the current value. `compareAndSet()` performs a conditional update: it writes the new value only if the current value equals the expected value. CAS is useful when the update depends on observing a particular previous state and can support lock-free algorithms.