AtomicStampedReference compares both a reference and a version stamp, so a stale compare-and-set can detect an intervening change that returned to the original reference.
Java AtomicStampedReference: reject a stale A-to-B-to-A update
Make history part of the condition
A worker reads READY. Another worker changes the state to PACKED and then back to READY. A reference-only comparison would see READY again and miss that history. Increment the stamp on each state transition; the original worker's stale stamp then fails. The fixture performs those transitions sequentially to make the result deterministic.
This is an in-process coordination tool. It does not provide database durability or a distributed version check. Atomic primitives cover single-reference updates; concurrent maps cover keyed state with different contracts.
Keep versions meaningful
A stamp can wrap after enough updates. Choose a version width and lifetime policy that fits the system, and do not treat the stamp as a cryptographic token. Compare-and-set still does not make a multi-object transaction atomic.
Working program
import java.util.concurrent.atomic.AtomicStampedReference;
public class ParcelStateVersion {
enum State { READY, PACKED, SHIPPED }
public static void main(String[] args) {
AtomicStampedReference<State> parcel = new AtomicStampedReference<>(State.READY, 1);
int staleStamp = parcel.getStamp();
parcel.set(State.PACKED, 2);
parcel.set(State.READY, 3);
boolean accepted = parcel.compareAndSet(State.READY, State.SHIPPED, staleStamp, 4);
System.out.println("accepted=" + accepted);
System.out.println(parcel.getReference() + ":" + parcel.getStamp());
}
}Output
accepted=false
READY:3Cost and ownership
Each operation uses constant application storage and an atomic reference update. Retries under contention can increase work; the example isolates the version condition and does not claim a latency bound.
Common Mistakes
- Do not compare only the current reference when intervening transitions matter.
- Do not use set as a conditional update in a contended workflow.
- Do not treat an in-memory stamp as a durable database version.
Read next
Java atomic variables: compare-and-set and one-variable invariants, Java ConcurrentHashMap: atomic updates and weakly consistent reads, Java VarHandle: atomic transitions and explicit access modes, volatile counter lost update.
