AtomicReferenceArray — 원자적으로 업데이트되는 객체 참조 배열

AtomicReferenceArray — 원자적으로 업데이트되는 객체 참조 배열

AtomicReferenceArray<E>는 배열의 각 요소를 개별적으로 원자적으로(atomically) 업데이트할 수 있게 해주는 클래스예요. 여러 스레드가 같은 배열의 서로 다른 인덱스를 동시에 수정해야 할 때, 동기화(Synchronized) 블록 없이도 안전하게 읽고 쓰고 비교 후 변경(CAS)까지 처리할 수 있어요.

출처: Java API Reference

본문

클래스 개요

AtomicReferenceArray는 요소들이 원자적으로 업데이트될 수 있는 객체 참조 배열이에요. 원자적 접근의 세부 속성은 VarHandle 명세를 따라요. 배열의 길이는 생성 시 고정되고, 개별 요소는 volatile 필드처럼 강한 메모리 효과(volatile read/write)를 지닌 채 접근돼요.

public class AtomicReferenceArray<E>
extends Object
implements Serializable

타입 매개변수 E는 배열에 담긴 요소의 기본 클래스예요. JDK 1.5부터 제공됐어요.

생성자

AtomicReferenceArray(int length)

주어진 길이의 AtomicReferenceArray를 만들고, 모든 요소를 처음에 null로 초기화해요.

  • length — 배열의 길이

AtomicReferenceArray(E[] array)

주어진 배열과 같은 길이를 갖고, 모든 요소를 복사한 AtomicReferenceArray를 만들어요.

  • array — 요소를 복사해 올 배열
  • NullPointerExceptionarraynull이면 던져져요

요소 접근·읽기

public final int length()

배열의 길이를 반환해요.

public final E get(int i)

인덱스 i의 요소 현재 값을 반환해요. 메모리 효과는 VarHandle.getVolatile(...)과 같아요.

  • i — 인덱스

public final E getPlain(int i) — 인덱스 i의 요소 값을, 변수가 volatile이 아닌 것처럼 읽는 일반(plain) 메모리 의미로 반환해요. (JDK 9+)

public final E getOpaque(int i)VarHandle.getOpaque(...)의 메모리 효과로 값을 반환해요. (JDK 9+)

public final E getAcquire(int i)VarHandle.getAcquire(...)의 메모리 효과(acquire)로 값을 반환해요. (JDK 9+)

요소 쓰기·설정

public final void set(int i, E newValue)

인덱스 i의 요소를 newValue로 설정해요. 메모리 효과는 VarHandle.setVolatile(...)과 같아요.

  • i — 인덱스
  • newValue — 새 값

public final void lazySet(int i, E newValue) — 인덱스 i의 요소를 newValue로 설정하되, VarHandle.setRelease(...)의 메모리 효과를 가져요. (JDK 1.6+)

public final void setPlain(int i, E newValue) — 요소를 변수가 volatilefinal도 아닌 것처럼 설정하는 일반 메모리 의미로 지정해요. (JDK 9+)

public final void setOpaque(int i, E newValue)VarHandle.setOpaque(...)의 메모리 효과로 설정해요. (JDK 9+)

public final void setRelease(int i, E newValue)VarHandle.setRelease(...)의 메모리 효과로 설정해요. (JDK 9+)

원자적 갱신(CAS) 계열

public final E getAndSet(int i, E newValue)

인덱스 i의 요소를 newValue로 원자적으로 설정하고 이전 값을 반환해요. (VarHandle.getAndSet)

public final boolean compareAndSet(int i, E expectedValue, E newValue)

요소의 현재 값이 == expectedValue일 때만 newValue로 원자적으로 설정해요. 성공하면 true를, 실제 값이 기대값과 다르면 false를 반환해요. (VarHandle.compareAndSet)

public final boolean compareAndExchange(int i, E expectedValue, E newValue) — 요소의 현재 값(witness 값)이 기대값과 같을 때만 새 값으로 설정하고, witness 값을 반환해요. 성공했다면 witness 값은 기대값과 같아요. (JDK 9+). compareAndExchangeAcquire/compareAndExchangeRelease 변형도 있어요.

@Deprecated(since="9") weakCompareAndSet(int i, E expectedValue, E newValue) — 메서드명과 달리 일반(plain) 메모리 효과만 지니는 옛 메서드라, 혼동을 피하려면 weakCompareAndSetPlain(...)을 쓰는 게 권장돼요. (JDK 1.6+)

weakCompareAndSetPlain / weakCompareAndSetVolatile / weakCompareAndSetAcquire / weakCompareAndSetRelease(int i, E expectedValue, E newValue) — 현재 값이 기대값과 같을 때만 "가능한 원자적으로(possibly atomically)" 설정하는 약한 CAS 변형들이에요. 성공하면 true를 반환해요. (JDK 9+)

함수 적용 계열

public final E getAndUpdate(int i, UnaryOperator<E> updateFunction)

주어진 함수를 적용한 결과로 인덱스 i의 요소를 원자적으로 갱신하고 이전 값을 반환해요. 함수는 스레드 경합으로 갱신이 실패하면 다시 적용될 수 있으므로 부작용이 없어야 해요. (JDK 1.8+)

public final E updateAndGet(int i, UnaryOperator<E> updateFunction) — 같은 방식으로 갱신하되 갱신된 값을 반환해요. (JDK 1.8+)

public final E getAndAccumulate(int i, E x, BinaryOperator<E> accumulatorFunction) — 현재 값과 주어진 값 x에 함수를 적용한 결과로 갱신하고 이전 값을 반환해요. 함수는 부작용 없는 2-인자 함수여야 해요. (JDK 1.8+)

public final E accumulateAndGet(int i, E x, BinaryOperator<E> accumulatorFunction) — 같은 방식으로 갱신하되 갱신된 값을 반환해요. (JDK 1.8+)

그 외

public String toString()

배열의 현재 값들을 문자열로 표현해 반환해요. (Object.toString 오버라이드)

더 알아보기 (Learn more)