【发布时间】:2020-09-13 19:42:06
【问题描述】:
标志变量不是易失的,所以我希望在线程 1 上看到一个无限循环。但我不明白为什么线程 1 可以看到标志变量上的线程 2 更新。
为什么非易失性变量在 CPU 共享缓存上更新?这里 volatile 和 non volatile 标志变量有区别吗?
static boolean flag = true;
public static void main(String[] args) {
new Thread(() -> {
while(flag){
System.out.println("Running Thread1");
}
}).start();
new Thread(() -> {
flag = false;
System.out.println("flag variable is set to False");
}).start();
}
【问题讨论】:
-
1.非
volatile并不意味着更改将不可见;只是没有担保。 2.println涉及同步,影响可见性。 -
out.println()在打印前缓冲文本。您可以使用System.err.println()立即获得结果 -
"这里的 volatile 和 non volatile 标志变量有区别吗?"也许。也许不吧。如果不是volatile,那么JVM可以选择。
-
关于非同步线程交互的问题是它们是*indeterminate.* 这意味着你无法确定它们将要做什么。
flag是否可见。它可能在一次代码运行时可见,而在下一次运行时不可见。如果硬件提供某种可见性保证(i86 硬件通常提供),JVM 没有义务删除它。关键是不保证非易失性字段不可见。他们的知名度可以是任何东西,这就是问题所在。 -
顺便说一句,Brian Goetz 在 Java 并发实践中详细介绍了这个(不确定的代码执行)。一本好书,你应该阅读它。
标签: java multithreading