在审核this question时我注意到这段代码:
class MyThread extends Thread {
private boolean stop = false;
public void run() {
while(!stop) {
doSomeWork();
}
}
public void setStop() {
this.stop = true;
}
}
但是我不明白为什么会失败。其他线程是否无法访问“实际”停止变量?
最佳答案
JIT 编译器可以重新排序应用程序中的读取和写入,只要
- Action 顺序一致并且
- 更改后的操作不会违反线程内语义。
这只是一种奇特的说法,所有操作的发生方式都应该与仅由单个线程执行相同。所以你可以让 JIT 重新编译你的代码,看起来像这样
class MyThread extends Thread {
private boolean stop = false;
public void run() {
if(!stop){
while(true){
}
}
}
这是一种称为“提升”的合法优化。提升。它的行为仍然与串行相同,但在使用多线程时提供令人惊讶的结果。
通过将字段声明为 volatile,您将告诉 Java 不要执行任何重新排序。以及 Nathan Hughes 提到的内存一致性
关于java - 为什么这段代码会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16346005/