并发之可见性
第一种情况:while空循环,永远无法获得主线程修改过的变量值
@Slf4j
public class TestVisibility {
private static boolean run = true;
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(()->{
TestVisibility.m();
});
t1.start();
Thread.sleep(1000);
run = false;
Thread.sleep(1000);
System.out.println(t1.isAlive());
}
public static void m() {
log.info("in");
while(run) {
}
log.info("out");
}
}
运行结果
第二种情况:while循环里面执行log.info(“running”),t1线程会获得主线程中对run变量的修改,t1线程会执行完毕
@Slf4j
public class TestVisibility {
private static boolean run = true;
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(()->{
TestVisibility.m();
});
t1.start();
Thread.sleep(1000);
run = false;
Thread.sleep(1000);
System.out.println(t1.isAlive());
}
public static void m() {
log.info("in");
while(run) {
log.info("running");
}
log.info("out");
}
}
运行结果
原因
- JVM会尽可能去保证内存的可见性,while进行空循环的时候会一直占用CPU,所以CPU没有时间去获取run的最新值,就会一直运行;
- 当在while循环里面进行打印的时候,CPU会有一点点点点的空闲时间,这个时候CPU去会去主存里面获取run的最新值,t1线程发现run
= false的时候就会退出循环,t1线程就会正常停止