为什么HotSpot会使用吊装优化以下内容?

在“Effective Java”中,作者提到了这一点

while (!done) i++; 

可以通过HotSpot进行优化

 if (!done) { while (true) i++; } 

我很困惑。 变量done通常不是const ,为什么编译器可以优化这种方式?

作者假设变量done是一个局部变量,它在Java Memory Model中没有任何要求将其值暴露给没有同步原语的其他线程。 或者换句话说:除了此处显示的内容之外,任何代码都不会更改或查看done的值。

在这种情况下,由于循环不会改变done的值,因此可以有效地忽略其值,并且编译器可以在循环外提升对该变量的求值,从而防止在“热”部分中对其进行求值。环。 这使循环运行得更快,因为它必须做更少的工作。

这也适用于更复杂的表达式,例如数组的长度:

 int[] array = new int[10000]; for (int i = 0; i < array.length; ++i) { array[i] = Random.nextInt(); } 

在这种情况下,天真的实现将评估数组的长度10,000次,但由于永远不会分配变量数组并且数组的长度永远不会改变,因此评估可以更改为:

 int[] array = new int[10000]; for (int i = 0, $l = array.length; i < $l; ++i) { array[i] = Random.nextInt(); } 

此处的其他优化也适用于与吊装无关。

希望有所帮助。

 public class StopThread { private static boolean stopRequested; private static synchronized void requestStop() { stopRequested = true; } private static synchronized boolean stopRequested() { return stopRequested; } public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!stopRequested()) i++; } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); } } 

上面的代码在有效代码中是正确的,相当于使用volatile来装饰stopRequested

 private static boolean stopRequested() { return stopRequested; } 

如果此方法省略synchronized关键字,则此程序运行不正常。
我认为当方法省略synchronized关键字时,此更改会导致提升

如果添加System.out.println("i = " + i); 在while循环中。 吊装不起作用,意味着程序按预期停止。 println方法是线程安全的,因此jvm无法优化代码段?