반응형
volatile 키워드 완벽 이해하기
많은 개발자가 처음에는 이렇게 생각합니다.
synchronized 있으면 끝 아닌가?
그런데 실제 멀티스레드에서는:
락(Lock) 문제
뿐 아니라
메모리 가시성(Memory Visibility)
문제도 존재합니다.
그리고 이 문제를 해결하기 위해 등장한 것이:
volatile
입니다.
실무 면접에서도:
volatile과 synchronized 차이를 설명해주세요.
는 정말 자주 나오는 질문입니다.
대표 이미지



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 알고리즘
까지 전부 연결됩니다.
반응형
'language > java' 카테고리의 다른 글
| Atomic 클래스 (AtomicInteger, AtomicLong 등) 완벽 이해하기 (0) | 2026.05.29 |
|---|---|
| CAS(Compare And Swap) 완벽 이해하기 (0) | 2026.05.29 |
| synchronized 원리 완벽 이해하기 (0) | 2026.05.29 |
| Thread와 Runnable 완벽 이해하기 (0) | 2026.05.29 |
| 프로세스(Process) vs 스레드(Thread) 완벽 이해하기 (0) | 2026.05.29 |
댓글