[Java] volatile
★발러틸로 발음하는 것 같다…
★volatile : 변수를 CPU의 cache가 아닌 Main Memory에 write하고, Main Memory에서 read하게 하는 키워드
★보통의 변수는 각 Thread가 작동되는 중에는 Main Memory가 아닌 해당 스레드가 작동중인 CPU cache에 우선적으로 저장된다. 그런데 이 상황에서 서로 다른 CPU cache를 사용중인 thread가 Main Memory의 변수를 공유한다면 thread별로 데이터 불일치가 발생할 수 있다. 예를 들어 1번 스레드가 main memory상의 값이 0인 num변수에 1을 더하고 1번 CPU cache에 저장(0 -> 1)했다. 그리고 동시에 2번 스레드가 main memory상의 num변수에 1을 더하고 2번 CPU cache에 저장(0 -> 1)했다. 이후 CPU cache의 값 1이 Main Memory에 저장되지만 실제로 더하는 연산은 2번했으므로 데이터가 제대로 반영되지 않은 것이다.
★이 상황에서 1번 스레드는 쓰기만 하고, 2번 스레드는 읽기만 하기로 프로그램을 변경했다. 1번 스레드가 더하기 연산을 100번을 하여 1번 CPU cache에 100을 저장했지만 2번 CPU cache의 값은 여전히 0이므로 역시 데이터의 불일치기 발생한다.
★이 때 Main Memory의 num변수에 volatile키워드를 달아 CPU cache와 함께 Main Memory에 바로 반영시키면 2번 스레드에서도 항상 최신의 값을 읽어올 수 있다.
★그러나 두 스레드가 모두 읽고 쓰는 연산을 동시에 한다면 1번 스레드가 Main Memory를 업데이트 함과 동시에 2번 스레드가 업데이트 전의 값을 가져와 다시 업데이트를 한다면 위와 같은 상황이 재현되게 된다. 그래서 volatile키워드는 여러 스레드가 동시에 write하는 상황에서는 적합하지 않다. 이 경우 synchronized키워드로 해당 변수를 동기화 시켜줘야 한다. 또한 volatile변수는 접근 비용이 더 큰 Main Memory에 저장되므로 CPU cache의 성능상 장점을 무효화 시킬 수 있으므로 반드시 변수가 일치해야 하고, write하는 스레드가 오직 하나인 경우에만 사용하는 것이 좋다.