Java / JVMadvanced검토 2026.08

Atomic Operation과 CAS

비교 후 교체하는 CAS로 단일 값의 원자적 갱신을 수행한다.

#Atomic#CAS

Overview

CAS는 값이 예상값과 같을 때만 새 값으로 교체하고 실패하면 다시 시도한다.

핵심 원리

짧은 경쟁에서는 Lock 없이 진행할 수 있지만 경쟁이 심하면 반복 실패가 CPU를 소모한다.

flowchart LR; R[Read] --> C{Compare}; C -->|same| S[Swap]; C -->|changed| R
Atomic Operation과 CAS 동작 흐름

실무에서 발생하는 문제

경쟁이 높으면 CAS 실패와 재시도가 늘어 CPU를 소모하고 Tail Latency가 커진다. 여러 필드의 불변식이나 ABA 문제는 단일 Atomic 값만으로 해결되지 않는다.

Trade-off

낮은 경쟁에서는 Blocking을 피하지만 높은 경쟁에서는 Spin 비용이 커진다. Lock은 대기 비용이 있지만 임계 구역과 조건을 명확하게 보호할 수 있다.

흔한 오해

Atomic 클래스를 사용해도 복합 연산 전체가 원자적인 것은 아니다. get()set()을 나누면 그 사이에 다른 Thread가 값을 바꿀 수 있다.

Interview Questions

  • 이 기술이 해결하는 핵심 문제는 무엇인가?
  • 내부에서는 어떤 순서로 동작하는가?
  • 운영 환경에서 어떤 지표와 실패 모드를 확인해야 하는가?

왜 필요한가

Counter처럼 하나의 값을 여러 Thread가 갱신할 때 읽기-수정-쓰기를 하나의 원자적 상태 전이로 만든다. 짧은 경쟁 구간에서 OS Lock 전환 없이 진행할 수 있다.

내부 동작

CPU의 조건부 원자 명령을 이용해 Memory의 현재 값이 예상 값과 같은 경우에만 새 값으로 바꾼다. 실패한 Thread는 최신 값을 읽고 함수를 다시 계산한다. Java Atomic 클래스의 갱신은 가시성 의미도 제공한다.

Example

counter.incrementAndGet()은 counter.get() + 1 후 set()과 다르다. 후자는 두 Thread가 같은 값을 읽어 증가분을 잃을 수 있다. updateAndGet에 전달하는 함수는 재시도 때 여러 번 실행될 수 있으므로 부수 효과를 넣지 않는다.

Production Considerations

CAS Retry 비율을 직접 제공하지 않는다면 CPU 상승, Thread Dump, 처리량 정체로 경쟁을 추론한다. 매우 뜨거운 Counter는 LongAdder처럼 분산 누적을 검토하되 즉시 정확한 단일 합계가 필요한지 확인한다.

Memory Visibility, synchronized, Redis 원자성과 보장 범위를 비교한다.

SOURCE REFERENCES

이 문서의 근거

본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.

원문 출처 보기 1