AtomicStampedReference — 스탬프가 붙은 원자적 참조
AtomicStampedReference — 스탬프가 붙은 원자적 참조
AtomicStampedReference<V>는 객체 참조(reference)와 정수 "스탬프(stamp)"를 한 쌍으로 묶어 둘 다 원자적으로 업데이트할 수 있게 해주는 클래스예요. 단순한 AtomicReference로는 해결하기 어려운 ABA 문제를 다룰 때 특히 유용해요.
본문
개념 이해하기
일반적인 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 반환)가 가능하지만, 현재 값이 기대값을 유지하고 다른 스레드가 설정을 시도하지 않는 한 반복 호출은 결국 성공해요.