본문 바로가기
language/java

Atomic 클래스 (AtomicInteger, AtomicLong 등) 완벽 이해하기

by 죄니안죄니 2026. 5. 29.
반응형

Atomic 클래스 (AtomicInteger, AtomicLong 등) 완벽 이해하기

이전 글에서:

  • synchronized
  • volatile
  • CAS(Compare And Swap)

를 배웠습니다.

이번에는 CAS를 실제 Java에서 사용할 수 있도록 만든:

Atomic 클래스

를 알아보겠습니다.

실무에서는 의외로 정말 많이 사용합니다.

특히:

 
조회수 증가
캐시 카운터
순번 생성
통계 수집
동시 접속자 수
 

같은 곳에서 자주 등장합니다.


1. Atomic 클래스란?

한 줄 정의.

CAS 기반으로 동작하는 Thread-Safe 클래스
 

입니다.


2. 대표 클래스

가장 많이 사용하는 것들.

 
AtomicInteger
AtomicLong
AtomicBoolean
AtomicReference<T>
 

3. 왜 등장했을까?

문제 코드.

 
private int count = 0;

public void increase() {

    count++;
}
 

멀티스레드 환경.

 
100개 Thread
 

동시 실행.


결과

100000 예상

↓

98231
 

가능.


4. synchronized 사용

 
public synchronized void increase() {

    count++;
}
 

문제 해결.


하지만

Lock 획득
대기
Context Switch
 

비용 존재.


5. Atomic 등장

 
private AtomicInteger count =
        new AtomicInteger();
 

증가

 
count.incrementAndGet();
 

6. 결과

Thread-Safe
 

보장.


7. 내부 원리

매우 중요.

AtomicInteger는

 
synchronized
 

를 사용하지 않는다.


실제로는

volatile
+
CAS
 

조합.


8. 내부 구조

개념적으로

 
public class AtomicInteger {

    private volatile int value;
}
 

9. 왜 volatile?

가시성 보장.


Thread A 수정.

Thread B 즉시 확인 가능.


10. 왜 CAS?

원자성 보장.


예:

 
incrementAndGet()
 

내부.


11. 개념 코드

 
for (;;) {

    int current = value;

    int next = current + 1;

    if (CAS(current, next)) {

        return next;
    }
}
 

12. 의미

현재값 읽기
 ↓
+1
 ↓
CAS 시도
 ↓
성공 → 종료

실패 → 다시
 

13. Lock-Free

Atomic의 가장 큰 특징.

락 사용 안 함
 

14. 그래서 빠름

synchronized

Lock
 ↓
Context Switch
 

Atomic

CAS
 ↓
끝
 

15. 가장 많이 쓰는 메서드


get()

조회.

 
count.get();
 

set()

설정.

 
count.set(10);
 

incrementAndGet()

증가 후 반환.

 
int value =
        count.incrementAndGet();
 

getAndIncrement()

반환 후 증가.

 
int value =
        count.getAndIncrement();
 

16. 차이

 
AtomicInteger count =
        new AtomicInteger(10);
 

 
count.incrementAndGet();
 

결과

11 반환
 

 
count.getAndIncrement();
 

결과

10 반환
 

이후 값

11
 

17. decrementAndGet()

감소.

 
count.decrementAndGet();
 

18. addAndGet()

더하기.

 
count.addAndGet(100);
 

19. compareAndSet()

매우 중요.

CAS 직접 사용.


 
count.compareAndSet(
        10,
        20
);
 

의미

현재값이 10이면

20으로 변경
 

20. 성공 여부 반환

 
boolean success =
    count.compareAndSet(
        10,
        20
    );
 

21. 실무 예제

조회수 증가.

 
private AtomicLong viewCount =
        new AtomicLong();
 

 
viewCount.incrementAndGet();
 

22. 접속자 수

 
private AtomicInteger userCount =
        new AtomicInteger();
 

로그인.

 
userCount.incrementAndGet();
 

로그아웃.

 
userCount.decrementAndGet();
 

23. 순번 생성기

 
private AtomicLong sequence =
        new AtomicLong();
 

 
long nextId =
    sequence.incrementAndGet();
 

24. AtomicBoolean

상태 관리.


 
AtomicBoolean running =
        new AtomicBoolean();
 

실행 중인지 확인.

 
running.get();
 

25. compareAndSet 활용

예:

 
if (running.compareAndSet(
        false,
        true
)) {

    start();
}
 

의미

실행 중이 아닐 때만 시작
 

26. AtomicReference

객체 참조용.


 
AtomicReference<User>
 

예:

 
AtomicReference<User> user =
    new AtomicReference<>();
 

27. 왜 필요할까?

객체 교체도 CAS 가능.


 
user.compareAndSet(
    oldUser,
    newUser
);
 

28. synchronized보다 무조건 좋을까?

아니다.


매우 중요.


29. Atomic이 좋은 경우

단일 변수
 

간단한 증가 감소
 

카운터
 

30. Atomic이 안 좋은 경우

복합 연산.


예:

 
if(count.get() < 100) {

    count.incrementAndGet();
}
 

31. 문제

Thread A

99 읽음
 

Thread B

99 읽음
 

둘 다 증가.


결과

101
 

가능.


32. 왜?

두 연산.

조회

+

증가
 

원자적이지 않음.


33. 이 경우

 
synchronized
 

또는

 
ReentrantLock
 

필요.


34. Atomic 클래스의 한계

Atomic은

변수 하나
 

를 안전하게 만들 뿐.


비즈니스 로직 전체를 보호하지 못함.


35. LongAdder 등장

실무 고급 주제.


예:

 
AtomicLong
 

1000개 Thread가 동시 접근.


CAS 실패 많아짐.


36. 해결

LongAdder


37. LongAdder 특징

내부 카운터를 여러 개 둠.


예:

Cell1
Cell2
Cell3
Cell4
 

각 Thread 분산 증가.


마지막 합산.


38. 경쟁 심할 때

LongAdder
 

AtomicLong
 

보다 빠를 수 있음.


39. 면접 단골 질문

Q. AtomicInteger는 어떻게 구현되나요?

volatile
+
CAS
 

Q. synchronized를 사용하나요?

아니오
 

Q. compareAndSet은 무엇인가요?

CAS 직접 수행
 

Q. AtomicInteger는 Thread-Safe인가요?

단일 변수에 대해 Yes
 

Q. AtomicInteger로 모든 동시성 문제 해결 가능한가요?

아니오
 

40. AtomicInteger vs synchronized


항목 AtomicInteger synchronized
Lock X O
CAS O X
Context Switch X O
단순 카운터 좋음 가능
복합 로직 어려움 가능

41. 실무 사용 빈도

생각보다 많음.

대표:

조회수
접속자 수
통계
캐시
Rate Limiter
Sequence
 

42. 핵심 흐름 요약

volatile
 ↓
Visibility 보장

CAS
 ↓
Atomicity 보장

AtomicInteger
 ↓
Lock-Free Thread-Safe
 

43. 가장 중요한 핵심 한 줄

Atomic 클래스는 volatile과 CAS를 이용하여 락 없이(Lock-Free) 단일 변수의 원자적 연산을 제공하는 Java 동시성 유틸리티이다.
 

44. 다음 글 예고

다음 글은:

Thread-safe 컬렉션

입니다.

여기서:

Vector
Collections.synchronizedList
CopyOnWriteArrayList
ConcurrentHashMap
 

이 왜 등장했는지,

일반 ArrayList/HashMap을 멀티스레드에서 쓰면 어떤 문제가 발생하는지부터 설명하게 됩니다.

반응형

댓글