我是Java并发编码的新手,遇到问题。以下代码在运行时无法停止。谁能告诉我为什么?谢谢
import java.util.concurrent.TimeUnit;
public class Test {
private static boolean stop;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
System.out.println(Thread.currentThread());
System.out.println(stop);
while (!stop) {
}
}).start();
TimeUnit.SECONDS.sleep(1);
stop = true;
System.out.println(Thread.currentThread());
System.out.println(stop);
}
}
我还尝试运行以下代码,它可能会停止。谁能告诉我为什么?谢谢
import java.util.concurrent.TimeUnit;
public class Test {
private static boolean stop;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
System.out.println(Thread.currentThread());
System.out.println(stop);
while (!stop) {
System.out.println(" ");
}
}).start();
TimeUnit.SECONDS.sleep(1);
stop = true;
System.out.println(Thread.currentThread());
System.out.println(stop);
}
}
答案 0 :(得分:8)
因为您没有向编译器指示stop
可能会被多个线程更改并读取:
private static boolean stop;
可以对此进行优化:
while (!stop) {
}
到
if (!stop) {
while (true) {
}
}
如果stop
最初为假,它将永远不会停止。
声明stop
volatile
:
private static volatile boolean stop;
不允许这种优化。
答案 1 :(得分:-3)
JVM通常在实际执行代码之前先对其进行优化。对于您而言,while(!stop){}
已优化为while(true){}
。发生这种情况是因为您没有通过同步函数显式访问静态变量,并且JVM假定该变量不会以线程不安全的方式进行更改。
为避免优化,请将任何内容放入while循环中。您可以执行以下操作:
while(!stop) {
try{
Thread.sleep(1); // You could also call any other function here.
}
catch(Exception e) { }
}
在这种情况下,JVM不会尝试优化,并且您的代码将按预期执行。
编辑:
尽管目前可以使用,但基于评论,我同意在将来的版本(或JDK / JVM的其他并行实现)中可以更改。将变量声明为volatile
是避免该优化的最佳方法。