[Java] Java volatile 이란?
1. Java volatile 이란?
- volatile 키워드란 Java 변수를 Main Memory에 저장하겠다는것을 명시한다
- 변수의 값을 read 할때마다 매번 CPU cache에 저장된 값을 가져오지 않고
Main Memory에서 읽는다
- 변수의 값을 write 할때마다 Main Memory 까지도 작성하는 것이다
2. 사용이유
- volatile 변수를 사용하고 있지 않는 MultiThread 어플리케이션에서는 Task를 수행하는 동안
성능 향상을 위해 Main Memory에서 읽은 변수 값을 CPU Cache에 저장하게 된다
- 만약에 Multi Thread환경에서 Thread가 변수 값을 읽어올 때 각각의 CPU Cache에 저장된 값이
다르기 때문에 변수 값 불일치 문제가 발생하게 된다
3. 예시
- SharedObject를 공유하는 두 개의 Thread가 있다
- Thread-1는 counter 값을 더하고 읽는 연산을 한다 (Read & Write)
- Thread-2는 counter 값을 읽기만 한다 (Only Read)
public class SharedObject {
public int counter = 0;
}
- Thread-1은 counter값을 증가시키고 있지만 CPU Cache에만 반영되어있고
실제로 Main Memory에는 반영이 되지 않았다
그렇기 때문에 Thread-2는 count값을 계속 읽어오지만 0을 가져오는 문제가 발생한다
4. 해결방법
- volatile 키워드를 추가하게 되면 Main Memory에 저장하고 읽어오기 때문에
변수 값 불일치 문제를 해결 할 수 있다
- Multi Thread 환경에서 하나의 Thread만 read & write하고 나머지 Thread가 read하는 상황에서 가장 최신의 값을 보장한다
public class SharedObject {
public volatile int counter = 0;
}
5. 예외
- Thread-1이 값을 읽어 1을 추가하는 연산을 진행
( 추가하는 연산을 했지만 아직 Main Memory에 반영되기 전 상황 )
- Thread-2이 값을 읽어 1을 추가하는 연산을 진행
( 추가하는 연산을 했지만 아직 Main Memory에 반영되기 전 상황 )
위와 같은 상황에서 두 개의 Thread가 1씩 추가하는 연산을 하여 최종결과가 2가 되어야 하는 상황
하지만 각각 결과를 Main Memory에 반영하게 된다면 1만 남는 상황이 발생하게된다
즉 하나의 Thread가 아닌 여러 Thread가 write하는 상황에서는 적합하지 않다
여러 Thread가 write하는 상황이면 synchronized를 통해 변수 read & write의 원자성(atomic)을 보장해야한다
6. 언제 쓰면 좋은가
- 하나의 Thread가 write하고 나머지 Thread가 읽는 상황인 경우
- 변수의 값이 최신의 값으로 읽어와야 하는 경우
7. 참고문헌
- http://tutorials.jenkov.com/java-concurrency/volatile.html
Java Volatile Keyword
The Java volatile keyword guarantees variable visibility across threads, meaning reads and writes are visible across threads.
jenkov.com