CAS (compare-and-swap) là một lệnh nguyên tử ở mức CPU (lock cmpxchg trên x86): "nếu ô nhớ đang bằng giá trị mong đợi thì ghi giá trị mới, ngược lại báo thất bại". Không có lock, không có block.
AtomicInteger.incrementAndGet() là một vòng lặp CAS: đọc giá trị hiện tại, tính giá trị mới, compareAndSet; thất bại thì lặp lại với giá trị vừa đọc được. Kiểu này gọi là lock-free — luôn có ít nhất một thread tiến lên, nhưng thread thua có thể phải quay vòng nhiều lần.
ABA problem: CAS chỉ so sánh giá trị, không so sánh lịch sử. Thread 1 đọc A, bị treo; thread 2 đổi A → B → A; thread 1 chạy tiếp, compareAndSet(A, ...) thành công vì "vẫn là A" — dù cấu trúc bên dưới đã thay đổi. Với số đếm thì vô hại, nhưng với con trỏ trong lock-free stack/queue thì có thể nối lại một node đã bị gỡ. Cách xử lý: gắn thêm số phiên bản bằng AtomicStampedReference (CAS kiểm tra cả tham chiếu lẫn stamp) hoặc AtomicMarkableReference.
LongAdder khi tranh chấp cao: với hàng chục thread cùng tăng một AtomicLong, tất cả CAS vào cùng một dòng cache → phần lớn CAS thất bại và phải lặp lại. LongAdder chia giá trị thành nhiều cell, mỗi thread chỉ CAS lên cell của nó, sum() cộng lại khi cần.
LongAdder hits = new LongAdder();
hits.increment(); // ghi rất nhiều, tranh chấp cao
long total = hits.sum(); // đọc thưaChọn: ghi nhiều đọc thưa (counter, metric) → LongAdder.
Cần đọc giá trị chính xác thường xuyên hoặc cần chính compareAndSet → AtomicLong; sum() của LongAdder không phải snapshot nguyên tử.