先看代码
public class Volatile {
/*volatile*/ private static boolean running = true;
private static void m() {
System.out.println("m starts");
while (running) {
}
System.out.println("m ends");
}
public static void main(String[] args) {
new Thread(Volatile::m, "t1").start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
running = false;
}
}
我们在主线程创建了一个 t1 线程,让它执行 Volatile 类的 m() 方法
随后我们把私有静态变量 running 的值由 true 改为 false,想以此来打断 m() 方法中的 while 循环
但是执行时会发现,程序打印"m starts"之后,迟迟不打印 while 循环结束后的 "m ends"
这是 线程本地缓存 导致的
虽然主进程中我们睡眠1秒后即将 running 的值改为了 false, 但是 t1 线程一直在读它缓存的值为 true 的 running, 所以 while 循环一直不会退出
处理该可见性问题的办法,使用 volatile 修饰 running, 使其值一旦发生变化,所有线程立即同步
缓存并不是发生在一个数据上,它以块为单位,叫做 cache line, 大小为 64Bytes
该概念会影响程序执行效率,所以在有的程序中你会看到一些在实际执行过程中没有被用到的变量存在