본문 바로가기

TIPS

Java Memory Model (JMM)과 volatile 키워드 — 동시성 프로그래밍의 핵심

728x90
반응형
SMALL

 

 

왜 알아야 할까?

 

  • 여러 스레드가 동시에 공유 변수를 읽고 쓸 때, 값이 예상대로 보장되지 않는 문제가 생긴다.
  • Java는 성능 최적화를 위해 JVM 레벨에서 변수 캐싱이나 명령어 재정렬(reordering) 을 수행한다.
  • 이런 최적화는 단일 스레드에서는 효과적이지만, 멀티스레드에서는 데이터 불일치를 초래한다.

 


 

예시: 잘못된 멀티스레드 동작
public class VisibilityProblem {
    static boolean isRunning = true;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (isRunning) {
                // isRunning 값이 변경되었는지 확인하려고 함
            }
            System.out.println("스레드 종료");
        }).start();

        Thread.sleep(1000);
        isRunning = false;
        System.out.println("isRunning을 false로 변경");
    }
}

 

예상 출력:

isRunning을 false로 변경 후 스레드 종료

실제 출력:

스레드 종료가 출력되지 않음

이유? → isRunning은 스레드 내 CPU 캐시에만 저장되어 다른 스레드의 변경을 감지하지 못함

 


 

해결법: volatile 사용
static volatile boolean isRunning = true;
 

 

  • volatile을 붙이면 모든 스레드가 메인 메모리의 값을 참조하도록 강제한다.
  • 가시성(visibility) 은 보장되지만, 원자성(atomicity) 은 보장하지 않는다.

 


 

volatile의 한계

 

static volatile int count = 0;

public static void main(String[] args) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    for (int i = 0; i < 1000; i++) {
        executor.execute(() -> count++);
    }
    executor.shutdown();
    Thread.sleep(1000);
    System.out.println("count = " + count);
}
 

결과: count < 1000

  • 이유: count++는 읽기 → 증가 → 쓰기의 복합 연산. 이 전체가 원자적이지 않음
  • 해결법: AtomicInteger 사용

 

AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); // 원자적 증가
 

 


 

volatile vs synchronized 차이

 

항목
volatile
synchronized
가시성
✅ 보장
✅ 보장
원자성
❌ 보장 안됨
✅ 보장
성능
빠름
느림
락(lock) 사용
❌ 없음
✅ 있음

 

 


정리

 

 

  • volatile은 가시성 문제 해결에만 유효하다.
  • 복잡한 연산이나 데이터 무결성이 중요한 경우, synchronized 또는 java.util.concurrent 패키지를 써야 한다.
  • Java Memory Model은 이런 동작이 정의된 기본 규약이며, 이를 잘 이해하면 스레드 간 충돌, 버그를 막을 수 있다.

 

 

 

 

 

학스의 개발일지

일상과 코딩 그 사이 어딘가에있는 블로그.. 블로거이자 빅데이터개발자 학스 입니다 JAVA, jQuery, PostgreSQL, MySQL, HIVE, Hadoop 더 많은 정보는 깃허브 주소 https://github.com/hacs2772 를 방문해주세요

hacs2772.tistory.com

 

728x90
반응형
LIST