为什么写入非易失性对主线程可见?
Why is the write to non-volatile visible to the main-thread?
想象一下下面的程序。
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);
}
}
主线程已缓存 whatever
并且 x
设置为 0
。另一个线程启动,缓存whatever
并将缓存的x
设置为1
。
输出为
1
所以主线程已经看到写入。这是为什么?
为什么对共享缓存进行了写入,为什么主线程使其缓存无效以从共享缓存读取?为什么我这里不需要 volatile
?
因为主线程加入了它。看
JLS 中的 17.4.5:
All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
顺便说一句,确实没有 happens-before 并不一定意味着某些东西不可见。
想象一下下面的程序。
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);
}
}
主线程已缓存 whatever
并且 x
设置为 0
。另一个线程启动,缓存whatever
并将缓存的x
设置为1
。
输出为
1
所以主线程已经看到写入。这是为什么?
为什么对共享缓存进行了写入,为什么主线程使其缓存无效以从共享缓存读取?为什么我这里不需要 volatile
?
因为主线程加入了它。看 JLS 中的 17.4.5:
All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
顺便说一句,确实没有 happens-before 并不一定意味着某些东西不可见。