스레드는 실행되고 있는 CPU 메모리 영역에 데이터 캐싱
그래서 스레드들의 변수 참조시 시점에 따라 값이 다를 수 있음.
volatile
CPU메모리 영역에 캐싱된 값이 아닌 항상 최신의 값을 가지도록 메모리 영역에서 값을 참조
하지만 아래와 같은 경우의 문제가 있다.
1) thread1 이 a(2)를 읽음 (Memory)
2) thread2 가 a(2)를 읽음 (Memory)
3) thread1 이 a를 3으로 변경
->a가 3으로 변경되었지만 시점차로 thread2는 a(2)를 갖고 있음.
volatile은 원자적 연산에서만 동기화 보장한다.
즉 한번만! 접근할때(원자적 연산)에서만 동기화보장된다.
원자적 연산이라 함은
a = 1; => 쓰기
flag= false; => 쓰기
b = a; => 읽기(a에서 읽어서 b에 저장하지만 변수 a의 관점에서는 단지 읽기 연산)
비원자적 연산일때 volatile은 책임질수 없다.
이때는
1. synchronized 키워드
무조건 락!
2. concurrent패키지의 atomic 클래스 사용
일부 락!