메모리 가시성, volatile

CPU는 처리 성능을 개선하기 위해 중간에 캐시 메모리라는 것을 사용한다.

여기서 핵심은 캐시 메모리의 runFlag 값만 변한다는 것이다! 메인 메모리에 이 값이 즉시 반영되지 않는다

멀티스레드 환경에서 한 스레드가 변경한 값이 다른 스레드에서 언제 보이는지에 대한 문제를 메모리 가시성 (memory visibility)이라 한다

한 스레드에서 변경한 값이 다른 스레드에서 즉시 보이게 하려면 어떻게 해야할까? (Main Thread, Worker Thread)

해결방안은 아주 단순하다 성능을 약간 포기하는 대신에, 값을 읽을 때, 값을 쓸 때 모두 메인 메모리에 직접 접근하면된다 → 자바에서는 volatile 이라는 키워드로 이런 기능을 제공한다.

Thread.sleep() , 콘솔에 출력등을 할 때 스레드가 잠시 쉬는데, 이럴 때 컨텍스트 스위칭이 되면서 주로 갱신 된다. 하지만 이것이 갱신을 보장하는 것은 아니다.

lass MyTask implements Runnable {
		 //boolean runFlag = true;
		 volatile boolean runFlag = true;

자바 메모리 모델(Java Memory Model)

Java Memory Model(JMM)은 자바 프로그램이 어떻게 메모리에 접근하고 수정할 수 있는지를 규정하며, 특히 멀티스레드 프로그래밍에서 스레드 간의 상호작용을 정의한다.

happens-before

happens-before 관계는 자바 메모리 모델에서 스레드 간의 작업 순서를 정의하는 개념이다. 만약 A 작업이 B 작업보다 happens-before 관계에 있다면, A 작업에서의 모든 메모리 변경 사항은 B 작업에서 볼 수 있다.

즉, A 작업에서변경된 내용은 B 작업이 시작되기 전에 모두 메모리에 반영된다.

정리

volatile 또는 스레드 동기화 기법(synchronized, ReentrantLock)을 사용하면 메모리 가시성의 문제가 발생하지않는다.