특징
- keyword로 Java 변수를 Main Memory에 직접 저장한다.
- 변수의 값을 Read 할 때마다 CPU Cache에 저장된 값이 아닌 Main Momory에서 직접 읽는다.
- 변수의 값을 Write할 때마다 Main Memory에 직접 작성한다.
필요성
- 멀티 스레드 환경에서 하나의 스레드가 Read&Write 하고 다른 스레드에서 Read 할 때, 해당 변수에 대한 최신 값을 보장한다.
예시
class Object {
public int count = 0;
}
위 Object를 공유하는 두 개의 스레드 A, B가 있다고 가정하자.
스레드 A는 count의 값을 읽고 1씩 증가시키는 연산(Read&Write)을 하고 스레드 B는 count를 읽는 연산만 수행한다(Read).
A는 count값을 증가시키지만 실제로 증가되고 있는 값은 CPU의 Cache 영역에만 반영되고 실제 Main Memory에는 바로 반영되지 않는다.
그러므로 스레드 B가 Read 연산을 수행해도 최신 데이터가 아닌 0이라는 값만 얻게 된다.
이때 volatile 키워드를 count에 추가해주면 Main Memory에 직접 값을 읽고, 저장하기 때문에 변숫값 불일치 문제를 해결할 수 있다.
class Object {
public volatile int count = 0;
}
한계점
volatile이 동기화 처리에 도움을 줄 수 있는 건 분명하지만 한계점도 존재한다.
만약 스레드 A, B가 count의 값을 1씩 증가시킨 후 아직 Main Memory에 캐시에 저장된 변수의 값을 반영하지 않았다면 기댓값은 2지만 실제 count의 값은 1이 된다.
즉, 하나가 아닌 여러 스레드가 write를 담당하는 상황에서 volatile는 불완전한 상태가 되어버린다.
여러 스레드가 동시에 write처리를 해야 한다면 synchronized 키워드를 사용하여 변수의 원자성을 보장해야 한다.
또한 CPU Cache 보다 Main Memory에 직접 접근하여 Read/Write 하는 것은 비용이 더 크므로 변수 값 일치가 보장되어야 할 때만 사용하는 것이 좋다.
'Java' 카테고리의 다른 글
[Java] 예외 종류 (0) | 2022.02.08 |
---|---|
[Java] Scanner와 BufferedReader (0) | 2020.11.23 |