为什么写入非易失性对主线程可见?

aku*_*ykh -1 java multithreading java-memory-model

想象一下下面的程序。

class Main {


    static class Whatever {
        int x = 0;
    }


    public static void main(String[] args) {
        Whatever whatever = new Whatever();

        Thread t = new Thread(() -> {
            whatever.x = 1;
        });
        t.start();
        try {
            t.join();
        }
        catch (InterruptedException e) {
        }

        System.out.println(whatever.x);
    }
}
Run Code Online (Sandbox Code Playgroud)

主线程已缓存whateverx设置为0。另一个线程启动、缓存whatever并将缓存设置x1.

输出是

1
Run Code Online (Sandbox Code Playgroud)

所以主线程已经看到了写入。这是为什么?

为什么写入共享缓存,为什么主线程使其缓存失效以从共享缓存读取?为什么我不需要volatile这里?

Nat*_*hes 5

因为主线程加入了它。参见 JLS 中的 17.4.5:

线程中的所有操作都发生在任何其他线程从该线程上的 join() 成功返回之前。

顺便说一句,没有发生之前并不一定意味着某些东西不可见,这是真的。