🔄 compareAndSet() vs weakCompareAndSet()
Both are methods in java.util.concurrent.atomic.* classes, like AtomicInteger, AtomicReference, etc.
They perform Compare-And-Swap (CAS) operations — which are the backbone of lock-free algorithms.
✅ compareAndSet(expectedValue, newValue)
- Checks if the current value equals
expectedValue. - If yes, sets it to
newValueatomically. - Returns
trueif successful. - Guaranteed to retry internally if necessary (strong semantics).
AtomicInteger counter = new AtomicInteger(10);
boolean success = counter.compareAndSet(10, 20); // true
This is the one most developers use — it’s safe, consistent, and works reliably across platforms.
⚡ weakCompareAndSet(expectedValue, newValue)
- Does the same logic, but may fail spuriously even if the values are equal.
- May return
falseeven if no other thread interfered. - Often used in tight loops, like:
do {
expected = atomic.get();
updated = doSomething(expected);
} while (!atomic.weakCompareAndSet(expected, updated));
It’s faster on some CPUs (especially ARM) that support weaker memory models.
⚠️ Why Would weakCompareAndSet() Fail Spuriously?
- Hardware-level optimizations and relaxed memory ordering can cause false negatives.
- On certain architectures, a weak CAS is cheaper and can avoid memory fences or retries.
- The method is allowed to fail even when it could succeed — so you must loop around it.
🧪 Summary Table
| Feature | compareAndSet() | weakCompareAndSet() |
|---|---|---|
| Guarantees | Strong CAS | Weak CAS (may fail spuriously) |
| Memory semantics | Full memory ordering | Possibly relaxed memory ordering |
| Retry needed | Usually not (internal retries) | Yes (should be in a loop) |
| Use case | General-purpose CAS | Low-level lock-free loops, fast paths |
🚀 When to Use Which?
| Situation | Use |
|---|---|
| Typical atomic updates | compareAndSet() |
| High-performance lock-free loops | weakCompareAndSet() (with retry) |