본문 바로가기
language/java

volatile 키워드 완벽 이해하기

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

volatile 키워드 완벽 이해하기

많은 개발자가 처음에는 이렇게 생각합니다.

synchronized 있으면 끝 아닌가?
 

그런데 실제 멀티스레드에서는:

락(Lock) 문제
 

뿐 아니라

메모리 가시성(Memory Visibility)
 

문제도 존재합니다.

그리고 이 문제를 해결하기 위해 등장한 것이:

volatile

입니다.

실무 면접에서도:

volatile과 synchronized 차이를 설명해주세요.
 

는 정말 자주 나오는 질문입니다.


대표 이미지

volatile 키워드
volatile 키워드volatile 키워드
 
 

 


1. synchronized로 해결 안 되는 문제

많은 사람들이:

멀티스레드 문제
=
Race Condition
 

만 생각합니다.

하지만 실제로는

Memory Visibility 문제
 

도 존재.


2. 예제

 
public class Flag {

    boolean stop = false;

    public void work() {

        while (!stop) {

        }

        System.out.println("종료");
    }
}
 

3. Thread A

 
flag.work();
 

4. Thread B

 
flag.stop = true;
 

5. 예상

stop=true
↓
while 종료
↓
"종료"
 

6. 실제

가끔

무한 루프
 

가능.


7. 왜 그럴까?

CPU 때문.


8. CPU는 매우 빠르다

메모리(RAM)는 상대적으로 느림.

그래서 CPU는

Cache Memory
 

를 사용.


9. 구조

RAM

 ↓

CPU Cache

 ↓

CPU Core
 

10. Thread A

stop=false
 

읽음.


CPU Cache 저장.


11. Thread B

 
stop = true;
 

실행.


12. 문제

Thread A는

자기 Cache
 

만 계속 보고 있을 수 있음.


13. 결과

RAM

stop=true
 

CPU Cache

stop=false
 

14. 이것이

Memory Visibility Problem
 

15. 메모리 가시성이란?

한 Thread가 수정한 값이

다른 Thread에서 보이는가?
 

문제.


16. 해결

volatile.


17. 선언

 
private volatile boolean stop;
 

18. 의미

한 줄 정의.

항상 메인 메모리 기준으로 읽고 쓴다.
 

19. 동작

Thread B

 
stop = true;
 

즉시 메인 메모리에 반영.


20. Thread A

 
while (!stop)
 

캐시가 아니라

메인 메모리 확인.


21. 결과

정상 종료.


22. volatile 핵심 역할

매우 중요.


가시성(Visibility) 보장
 

하지만

원자성(Atomicity) 보장 X
 

23. 원자성이란?

한 번에 실행되는 것.


예:

 
count++;
 

실제로는

읽기

+

1

저장
 

3단계.


24. volatile 붙이면?

 
volatile int count;
 

 
count++;
 

안전할까?


25. 정답

아니다.


26. 왜?

volatile은

값이 보이는 것만 보장
 

연산 보호 안 함.


27. 예시

Thread A

count 읽기 = 5
 

Thread B

count 읽기 = 5
 

Thread A

6 저장
 

Thread B

6 저장
 

결과

7이 아니라 6
 

28. 즉

Race Condition 발생 가능
 

29. 그래서 중요한 문장

면접 단골.

volatile은 Visibility는 보장하지만
Atomicity는 보장하지 않는다.
 

30. synchronized와 비교


항목 volatile synchronized
Visibility O O
Atomicity X O
Lock 사용 X O
성능 빠름 느림

31. synchronized는 왜 Visibility도 보장할까?

락 획득 시

CPU Cache Flush
 

발생.


락 해제 시

메인 메모리 반영
 

발생.


그래서:

Visibility + Atomicity
 

둘 다 보장.


32. volatile이 적합한 경우

대표 사례.


33. 종료 플래그

 
private volatile boolean stop;
 

매우 흔함.


34. 설정값

 
private volatile int refreshInterval;
 

읽기 많음.

쓰기 적음.


35. Singleton Double Check

면접 단골.


예:

 
private static volatile Singleton instance;
 

왜 volatile 필요?

다음 글(CAS 전후)에서 설명.


36. Java Memory Model(JMM)

매우 중요.


Java Memory Model


JMM은

Thread 간 메모리 접근 규칙
 

정의.


37. Happens-Before

면접 단골.


한 줄 정의.

A가 끝나면
B는 반드시 볼 수 있음
 

38. volatile 규칙

예:

 
x = 10;

volatileFlag = true;
 

다른 Thread

 
if(volatileFlag)
 

x=10 보장
 

39. 이것이 Happens-Before


40. CPU 재정렬 문제

컴파일러와 CPU는

성능 때문에

명령어 순서 변경
 

가능.


41. volatile 역할

재정렬 방지
 

효과도 일부 제공.


42. Double Checked Locking

유명한 예제.

 
if(instance == null) {

    synchronized(...) {

        if(instance == null) {

            instance =
                new Singleton();
        }
    }
}
 

여기서

 
volatile Singleton instance
 

필수.


43. 실무에서 자주 하는 실수

1)

 
volatile int count;
count++;
 

안전하다고 착각.


2)

모든 변수에 volatile 사용.

불필요.


3)

volatile = thread-safe

라고 생각.


절대 아님.


44. volatile이 적합한 상황

읽기 많음
 

쓰기 적음
 

단순 상태 공유
 

Atomic 연산 불필요
 

45. volatile이 부적합한 상황

 
count++;
 

 
balance += money;
 

 
list.add(...)
 

상태 변경 연산.


46. 면접 단골 질문

Q. volatile 역할은?

Visibility 보장
 

Q. volatile은 thread-safe인가?

아니다
 

Q. count++는 안전한가?

아니다
 

Q. synchronized와 차이는?

volatile

=
Visibility

synchronized

=
Visibility + Atomicity
 

47. 핵심 흐름 요약

Thread A 수정
 ↓
메인 메모리 반영
 ↓
Thread B 읽기
 ↓
항상 최신값 확인
 

48. 가장 중요한 핵심 한 줄

volatile은 스레드 간 값의 가시성(Visibility)을 보장하지만, 연산의 원자성(Atomicity)은 보장하지 않는다.
 

49. 다음 글 예고

다음 글은:

CAS (Compare And Swap)

입니다.

여기서부터는:

synchronized 없이
어떻게 Atomic 연산을 수행할까?
 

를 배우게 됩니다.

그리고:

CAS
↓
AtomicInteger
↓
ConcurrentHashMap
↓
Lock-Free 알고리즘
 

까지 전부 연결됩니다.

반응형

댓글