개요

자바의정석 chapter 13 - 멀티코어 프로세서의 캐시와 메모리간의 통신

자바의정석 chapter 13 - 멀티코어 프로세서의 캐시와 메모리간의 통신

멀티 코어 프로세서는 각각의 코어가 별도의 캐시를 가지고 있다.

그리고 각각의 코어는 메모리에서 읽어온 값을 캐시에 저장하고 읽어서 작업을 수행하는데,

같은값을 다시 읽을때는 먼저 캐시를 확인 후 없을때만 메모리에서 읽어온다.

그러다보니 위 그림처럼 코어의 캐시에 저장된 값과 메모리에 저장된 값이 불일치하는 경우가 생길 수 있다.

그래서 나온게 volatile 이라는 키워드이고 해당 키워드를 이용해 이러한 문제를 해결한다.

Q.어떻게? A. volatile 키워드를 붙힐 경우 코어가 변수의 값을 캐시가 아닌 메모리에서 읽는다.

Happends-Before

JDK 5부터 volatile 키워드는 단순히 해당 변수의 작업(읽기/쓰기)의 원자성만 보장하는 것이 아니라 이 스레드가 volatile 변수를 수정하기 전에 수정한 모든 변수들이 함께 메모리에 저장(flushed)된다.

volatile 변수를 메모리에서 읽을때도 마찮가지로 다른 모든 변수들도 같이 읽어들여진다.

주의점

volatile 키워드는 변수의 작업(읽기/쓰기)를 원자화 하는 것이지 동기화 하는 것은 아니다.

즉 동기화가 필요할 때 volatile이 synchronized 블럭을 대체할 수 없다는 의미이다.

volatile long balance;

synchronized int getBalance() {
		return balance;
}

synchronized void withdraw(int money){
		if(balance >= money) {
				balance -= money;
		}
}

⇒ balance 변수가 volatile로 작업을 원자화 했으니 getBalance의 synchronized 키워드가 불필요해보일 수 있다. 하지만 해당 키워드로 동기화를 하지 않을 경우 특정 스레드에서 withdraw()가 호출되어 lock이 걸리고 로직이 처리되는 중에도 getBalance() 가 호출이 가능해질 수 있다.