Den*_*er9 5 java timer while-loop timertask
运行此代码,我希望它将测试变量增加5秒然后完成.
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static boolean running;
public static void main( String[] args ) {
long time = 5 * 1000; // converts time to milliseconds
long test = Long.MIN_VALUE;
running = true;
// Uses an anonymous class to set the running variable to false
Timer timer = new Timer();
timer.schedule( new TimerTask() {
@Override
public void run() { running = false; }
}, time );
while( running ) {
test++;
}
timer.cancel();
System.out.println( test );
}
}
Run Code Online (Sandbox Code Playgroud)
然而,当我运行它时,程序没有结束(我假设,我给了它一段合理的时间).但是,如果我将while循环更改为
while( running ) {
System.out.println();
test++;
}
Run Code Online (Sandbox Code Playgroud)
程序在预期的时间内完成(并打印出很多行).我不明白.为什么会出现这种情况?
根据Java 内存模型,无法保证非易失性字段何时对另一个线程可见。在您的情况下,您的 main 方法是 JIT 编译的,并且 JIT 编译器合理地假设,由于当前线程不会修改running
循环中的变量,那么我们不应该在每次迭代时读取它并将循环转换为无限循环。FindBugs甚至针对此案例发出了警告。
当你添加一个System.out.println
调用时,似乎JIT编译器无法内联它,因此无法确定该方法不会修改变量running
,因此它关闭了字段读取优化。然而,这不应该被视为问题的解决方案:即使你有内部循环,新版本的 Java 也可能会更智能并优化你的循环System.out.println
。