Las clases atómicas proveen operaciones indivisibles sin bloqueos en hardware moderno. Son ideales para contadores, flags y referencias simples.
AtomicIntegerAtomicLongAtomicBooleanAtomicReference<T>AtomicStampedReference<T> (previene ABA con sello/versión: detecta cuando un valor cambia A→B→A y evita aceptarlo por error).getAndIncrement() / incrementAndGet(): incrementos atómicos con retorno previo o posterior.compareAndSet() (CAS): cambia el valor si coincide con el esperado.lazySet(): publica el valor con ordenamiento relajado (puede retrasar visibilidad).import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
public class ContadorAtomicoDemo {
private static final AtomicInteger contador = new AtomicInteger(0);
private static final AtomicStampedReference<String> ref =
new AtomicStampedReference<>("v1", 1);
public static void main(String[] args) throws InterruptedException {
Runnable tarea = () -> {
for (int i = 0; i < 1_000; i++) {
contador.incrementAndGet();
}
};
Thread t1 = new Thread(tarea, "t1");
Thread t2 = new Thread(tarea, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Contador atómico: " + contador.get()); // 2000
int[] stampHolder = new int[1];
String valor = ref.get(stampHolder);
int version = stampHolder[0];
boolean actualizado = ref.compareAndSet("v1", "v2", version, version + 1);
System.out.println("CAS con sello: " + actualizado + " valor=" + ref.getReference() +
" version=" + ref.getStamp());
}
}
El ejemplo usa dos hilos que incrementan un AtomicInteger sin locks y muestran el valor final esperado (2000). Luego obtiene el sello actual de AtomicStampedReference y aplica compareAndSet verificando tanto el valor como la versión para evitar el problema ABA (cambios A→B→A). Si coinciden, actualiza a "v2" y aumenta el sello.
synchronized en contadores y flags.