不加volatile ,共享变量不是不可见吗,为什么子线程修改flag后,主线程可见了,一直处于死循环?

不加volatile ,共享变量不是不可见吗,为什么子线程修改flag后,主线程可见了,一直处于死循环?

public class A {
    private static boolean flag = false;

    public static void main(String[] args) throws Exception {

        new Thread(() -> {
            flag = true;
        }).start();

        Thread.sleep(1000);

        while(flag) {

        }
    }
}

不可见不是说不能访问,而是说可能出现不同步的情况(每个线程存在变量的副本)
之所以死循环,是flag被修改为true后,没有地方再修改回 false

不加volatile的共享变量,每个子线程使用到该共享变量都是独立的副本,互不可见,也就是说子线程1修改该共享变量,在子线程2中是看不到该变量的变化的,volatile的共享变量,任何一个子线程该变量的副本发生变化,其他线程的变量副本立即得到最新值。

再说回你这个例子,子线程退出之前的某个时候,子线程的共享变量副本值(true)回写到共享变量中,所以进入无限循环。