IT 전공

java volatile (재정렬 방지)

hyuktech 2025. 10. 19. 20:40
반응형

 

volatile

  • 자바에서 volatile 키워드를 붙이면, 그 변수는 CPU 캐시를 거치지 않고 메인 메모리에서 직접 읽고 쓰기 하도록 보장됩니다.
  • 여러 스레드가 동시에 그 변수를 읽더라도 최신 값을 보게 됩니다. (가시성 Visibility 보장)
  • 또한, 재정렬 방지 (reordering) 효과도 있어서 변수의 쓰기와 읽기 순서가 보장됩니다.

 

 

하지만 원자성 까지는 보장하지 않는다.

class Counter {
    volatile int count = 0;

    void increment() {
        count++; // 원자적이지 않음!
    }
}
 

멀티 스레드 환경에서 여러 스레드가 동시에 실행되면 꼬인다.

 

 

재정렬 개념도 보면 좋다.

class ReorderExample {
    int a = 0;
    boolean flag = false;

    public void writer() {
        a = 1;          // (1)
        flag = true;    // (2)
    }

    public void reader() {
        if (flag) {     // (3)
            System.out.println(a); // (4)
        }
    }
}
 

보통 flag == true 면 a 는 이미 1이라고 생각하지만

JVM / CPU 는 최적화를 위해 (1), (2)의 순서를 재정렬할 수 있다.

 

실제로 실행 순서가 아래처럼 될 수 있다.

flag = true;
a = 1;
 

이 때 다른 스레드는 flag = true 인데 a 가 0 인 상태가 될 수 있다.

 

순서를 보장하기 위해 다음과 같이 작성하면 된다.

class ReorderExample {
    int a = 0;
    volatile boolean flag = false;

    public void writer() {
        a = 1;
        flag = true; // volatile write
    }

    public void reader() {
        if (flag) { // volatile read
            System.out.println(a);
        }
    }
}
 

volatile 로 인해 flag = true 이전의 모든 쓰기(a=1) 과정이 반드시 먼저 실행되는 것을 보장한다.

 

반응형