AtomicStampedReference — 스탬프가 붙은 원자적 참조

AtomicStampedReference — 스탬프가 붙은 원자적 참조

AtomicStampedReference<V>는 객체 참조(reference)와 정수 "스탬프(stamp)"를 한 쌍으로 묶어 둘 다 원자적으로 업데이트할 수 있게 해주는 클래스예요. 단순한 AtomicReference로는 해결하기 어려운 ABA 문제를 다룰 때 특히 유용해요.

출처: Java API Reference

본문

개념 이해하기

일반적인 CAS(compare-and-set)에서는 값이 A였다가 B로 바뀌었다가 다시 A로 돌아오는 ABA 문제가 생길 수 있어요. 이때 참조와 함께 "버전 번호" 역할을 하는 정수 스탬프를 바꿔가며 업데이트하면, A로 돌아와도 스탬프가 다르므로 이전 상태인지 구분할 수 있어요.

구현 상세로는, 이 클래스가 [참조, 정수] 쌍을 감싼 내부 객체를 만들어 "박싱된(boxed)" 스탬프 참조를 유지해요.

public class AtomicStampedReference<V>
extends Object

타입 매개변수 V는 이 참조가 가리키는 객체의 타입이에요. JDK 1.5부터 제공됐어요.

생성자

public AtomicStampedReference(V initialRef, int initialStamp)

주어진 초기 값들로 새 AtomicStampedReference를 만들어요.

  • initialRef — 초기 참조
  • initialStamp — 초기 스탬프

값 읽기

public V getReference()

참조의 현재 값을 반환해요.

public int getStamp()

스탬프의 현재 값을 반환해요.

public V get(int[] stampHolder)

참조와 스탬프의 현재 값을 둘 다 반환해요. 스탬프는 반환값이 아니라 배열에 담겨 나와요.

  • stampHolder — 크기가 1 이상인 배열. 반환 시 stampHolder[0]에 스탬프 값이 담겨요.
int[] holder = new int[1];
V ref = v.get(holder);       // holder[0] = stamp

값 설정·갱신

public boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)

현재 참조가 == 기대 참조이고 현재 스탬프가 기대 스탬프와 같을 때만, 참조와 스탬프를 둘 다 주어진 값으로 원자적으로 설정해요. 성공하면 true를 반환해요.

  • expectedReference — 기대 참조 값
  • newReference — 새 참조 값
  • expectedStamp — 기대 스탬프 값
  • newStamp — 새 스탬프 값

public boolean weakCompareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)

compareAndSet과 유사하지만 가짜 실패가 가능하고 순서 보장이 없어요. compareAndSet의 대안으로는 드물게 적절해요.

public void set(V newReference, int newStamp)

조건 없이(unconditionally) 참조와 스탬프를 둘 다 설정해요.

public boolean attemptStamp(V expectedReference, int newStamp)

현재 참조가 == 기대 참조일 때만 스탬프를 주어진 값으로 원자적으로 설정해요. 가짜 실패( false 반환)가 가능하지만, 현재 값이 기대값을 유지하고 다른 스레드가 설정을 시도하지 않는 한 반복 호출은 결국 성공해요.

더 알아보기 (Learn more)