[Java] AtomicReference
AtomicReference, java.util.concurrent.atomic.AtomicReference, 원자 참조
정의
java.util.concurrent.atomic.AtomicReference<V> 는 객체 참조를 atomic 하게 갱신 하는 래퍼. volatile 참조 + CAS 의 결합.
AtomicInteger 의 객체 버전. 불변 객체 패턴, 상태 머신, lock-free 자료구조의 빌딩 블록.
핵심 메서드
AtomicReference<Config> ref = new AtomicReference<>(initial);
ref.get(); // 현재 참조
ref.set(newConfig); // 단순 설정 (volatile write)
ref.compareAndSet(expected, newVal); // CAS, 성공 시 true
ref.getAndSet(newVal); // 이전 값 반환 + 새 값으로
ref.updateAndGet(c -> c.withFoo("x")); // 람다로 갱신 (CAS 루프 내장)
ref.accumulateAndGet(arg, (cur, a) -> ...);
가장 흔한 패턴, 불변 객체 교체
class ConfigHolder {
private final AtomicReference<Config> ref = new AtomicReference<>(defaultConfig);
public Config get() { return ref.get(); }
public void reload(Config newConfig) {
ref.set(newConfig); // volatile write, 다른 스레드 즉시 봄
}
public void update(Function<Config, Config> updater) {
ref.updateAndGet(updater); // CAS 루프, 동시 update 안전
}
}
Config 가 불변 이면 한 번 참조한 객체는 변하지 않는다. 새 설정으로 교체할 때 참조만 atomic 하게 바꾸면 안전. CopyOnWriteArrayList 의 사상.
사용 사례
1. lock-free 단일 객체 swap
private final AtomicReference<Snapshot> snapshot = new AtomicReference<>();
// Writer
snapshot.set(takeSnapshot());
// Reader (lock-free)
Snapshot s = snapshot.get();
process(s);
2. 상태 머신
enum State { READY, RUNNING, STOPPED }
private final AtomicReference<State> state = new AtomicReference<>(State.READY);
public boolean start() {
return state.compareAndSet(State.READY, State.RUNNING);
}
3. lock-free 자료구조의 노드 포인터
class Node<E> {
final E value;
AtomicReference<Node<E>> next;
}
ConcurrentLinkedQueue 의 internal pattern.
ABA 문제와 해법
AtomicInteger 와 같은 ABA 문제. 해법.
AtomicStampedReference<V>: stamp (int 버전) 추가AtomicMarkableReference<V>: boolean mark 추가 (삭제 표시 등)
AtomicStampedReference<Node> ref = new AtomicStampedReference<>(node, 0);
int[] stampHolder = new int[1];
Node current = ref.get(stampHolder);
ref.compareAndSet(current, newNode, stampHolder[0], stampHolder[0] + 1);
참고
이 글의 용어 (5개)
- [Java] AtomicIntegerjava
- 정의 는 lock-free 로 원자성을 보장 하는 래퍼. 내부적으로 CAS (Compare-And-Swap) 를 사용해 락 없이 atomic 한 read-modify-write …
- [Java] ConcurrentLinkedQueuejava
- 정의 는 lock-free 로 구현된 unbounded thread-safe . Michael & Scott 의 non-blocking queue 알고리즘 (1996) 기반. 가…
- [Java] CopyOnWriteArrayListjava
- 정의 는 쓰기 시 배열 전체를 복사 하는 thread-safe 구현. 읽기에는 lock 이 전혀 없고, 쓰기에는 으로 직렬화한다. (JSR-166) 의 컬렉션. 읽기 압도적 다,…
- [Java] volatilejava
- 정의 은 Java 의 키워드. 필드에 붙이면 두 가지를 보장한다. 1. 가시성 (visibility): 한 스레드의 쓰기가 다른 모든 스레드에 즉시 보인다. CPU 캐시에 머무르…
- Non-Blocking (논블로킹)concurrency
- 정의 Non-Blocking 은 호출이 결과를 기다리지 않고 즉시 반환 하는 실행 방식. 결과가 준비되지 않았다면 "아직 안 됐다" 라는 신호 ( , , , 등) 를 반환하고, …
💬 댓글