Contents

volatile

volatile란?

volatile 키워드는 java 변수를 Main Memory에 저장하겠다라는 것을 명시한다. 즉 매번 변수의 값을 읽을 때마다 CPU cache에 저장된 값이 아닌 Main Memory에서 읽는 것이다. 또한 변수의 값을 쓸 때마다 Main Memory까지 작성한다.

volatile 키워드의 필요성

멀티쓰레드 어플리케이션에서의 non-volatile 변수에 대한 작업은 성능상의 이유로 CPU 캐시를 이용한다. 둘 이상의 CPU가 탑재된 컴퓨터에서 어플리케이션을 실행한다면, 각 쓰레드는 변수를 각 CPU의 캐시로 복사하여 읽어들인다.

쓰레드가 변경한 값이 메인 메모리에 저장되지 않아서 다른 쓰레드가 이 값을 볼 수 없는 상황을 ‘가시성’ 문제라 한다. 한 쓰레드의 변경(update)이 다른 쓰레드에게 보이지 않는다.

변수에 volatile 키워드를 선언한다면 이 변수에 대한 쓰기 작업은 즉각 메인 메모리로 이루어질 것이고, 읽기 작업 또한 메인 메모리로부터 다이렉트로 이루어질 것이다. 따라서 가시성 문제가 해결된다.

volatile 사용 시 주의할 점

  1. 한 변수를 두고 오직 한 쓰레드만 이 변수에 읽기/쓰기 작업을 하고, 다른 쓰레드들은 읽기 작업만 하는 상황에서라면 이 때는 volatile 선언이 유효하다. 읽기 작업을 수행하는 쓰레드들은 언제나 이 변수의 가장 최근 수정된 값을 봐야하고, volatile 은 이를 보장해준다. 그러나 하나의 Thread가 아닌 여러 Thread가 write하는 상황에서는 적합하지 않다. 여러 Thread가 write하는 상황이라면 synchronized를 통해 변수 read & write의 원자성(atomic)을 보장해야 한다.

  2. volatile 변수의 읽기/쓰기는 메인 메모리를 이용한다. 메인 메모리로부터 데이터를 읽고 쓰는 작업은 CPU 캐시를 이용하는 것 보다 많은 비용이 요구된다. 따라서 변수 값 일치을 보장해야 하는 경우에만 volatile 사용하는 것이 좋다.

  3. volatile 선언은 JVM 의 성능 향상을 위한 기술인 코드 재정리를 막기도 한다. 그러므로 volatile 키워드는 변수의 가시성 보장이 반드시 필요한 경우에만 사용되어야 한다.

참고

https://junghyungil.tistory.com/99