【发布时间】:2021-04-03 17:37:33
【问题描述】:
最近在一次会议演讲中,以下面的例子来演示多线程环境中的 Java 内存模型。
public class A {
public static boolean done;
public static void main(String[] args) throws InterruptedException {
done = false;
new Thread(new Runnable(){
public void run() {
System.out.println("running...");
int count = 0;
while (!done) {
count++;
}
System.out.println("Exiting thread");
}
}).start();
System.out.println("in main...");
Thread.sleep(2000);
System.out.println("setting done to true");
done = true;
}
}
我知道上面代码中创建的新线程永远不会退出,因为done 变量被缓存在线程的本地缓存中。一个适当的解决方案是使done 变量可变。
但是如果在while循环中,我们调用Thread.sleep()如下
while (!done) {
count++;
try {Thread.sleep(0);} catch(Exception e){}
}
然后线程成功退出。
我的理解是,由于sleep(0) 会发生上下文切换,这将使缓存条目无效,因此每次检索done 的更新值。我的理解正确吗?这种行为是否也取决于机器的核心数量?
【问题讨论】:
-
它可能发生线程永远不会完成或者它可能。这就是重点:在内存模型中,您无法保证一种或另一种方式。某些特定操作可能会导致从主内存重新读取
done,但这完全取决于实现(当然在指定的读取障碍之外)。
标签: java multithreading java-memory-model