volatile ==> 캐시메모리가아니라 메인메모리에 있는거로 참조하도록 변경
=============================================
package thread.volatile1;
import static util.MyLogger.log;
import static util.ThreadUtils.sleep;
public class VolatileFlagMain {
public static void main(String[] args) {
MyTask task = new MyTask();
Thread t = new Thread(task, "work");
log("runFlag = " + task.runFlag);
t.start();
sleep(1000);
log("runFlag 변경 시도");
task.runFlag = false;
log("runFlag = " + task.runFlag);
log("main 종료");
}
static class MyTask implements Runnable{
boolean runFlag = true;
@Override
public void run() {
log("task 시작");
while ( runFlag ) {
}
log("task 종료");
}
}
}
===> task 종료가 나오지않음 ( 스레드 종료 ㄴㄴ. == > while 문을 계속 ... ).
왜 이러한 방식으로 작동 ?
===> 캐시메모리때문에
그럼 캐시메모리 ?
//// 메인메모리랑 CPU 의 거리? 때문에 값을 읽어들이고 처리하는게 오래걸림 ..
그래서, 정보를 처리하는 CPU 근처에 메모리에 해당하는 값들을 배치... => 캐시메모리 공간에 저장
즉, 메모리에 저장되어져있는 runFlag = true // 를 캐시메모리에 복사해서 저장
==================
runFlag 변경시도 : ==> main 스레드에서 변경 /// ==> main 스레드에 해당하는 cpu 에 있는 캐시메모리에 값 ( runFlag ) 를 변경
반면에, main 스레드가 아닌 다른 스레드인 t 스레드에 해당하는 cpu 에 있는 캐시메모리 값 ( runFlag ) 는 변경이 되지않았음 ( 아직 true )
그래서, 계속해서 while 문을 돌고있는 상태 ...
그러면, 결국 캐시메모리때문에 문제가 생긴것이니...
직접 메인메모리에있는 값 ( runFlag ) 를 변경해주면됨
==> 그럼이제 메인메모리를 참조하도록 할려면 어떻게해야함 ? ==> volatile 키워드 사용 ㄱㄱ
package thread.volatile1;
import static util.MyLogger.log;
import static util.ThreadUtils.sleep;
public class VolatileFlagMain {
public static void main(String[] args) {
MyTask task = new MyTask();
Thread t = new Thread(task, "work");
log("runFlag = " + task.runFlag);
t.start();
sleep(1000);
log("runFlag 변경 시도");
task.runFlag = false;
log("runFlag = " + task.runFlag);
log("main 종료");
}
static class MyTask implements Runnable{
volatile boolean runFlag = true;
@Override
public void run() {
log("task 시작");
while ( runFlag ) {
}
log("task 종료");
}
}
}
==> volatile boolean runFlag = true;
/// runFlag 값은 메인메모리에있는거로 참조하셈 ( 캐시메모리 말고 )