Java: 没有volatile变量就关机?

Java: Shutdown without a volatile variable?

以下场景:

我有一个应用程序,它运行了数周,然后我想正常关闭它。

以下代码可以解决问题:

Main-Thread:

boolean volatile active=true;

while(active)
{
    //loop-code (very fast)
}


//shutdown-thread, called once after a few weeks

active=false;

所以现在在每次循环迭代之后,我都会在主内存中查找,这是易失性读取的原因(对吧?!)。

而且我不想要那个,只是为了几周后的关机。

是否有任何其他解决方案,让我的主线程收到有关关闭的通知?

任何直接进入主线程缓存的信号?这样它就不必每次都在主内存中查找自己,而是从 extern?

或任何其他解决方案?

编辑(将我自己的答案融入到这个问题中):

一种可能的解决方案是,减少易失性访问,请参见以下代码:

boolean volatile active=true;


while(active)
{
    for(int i=0; i<100; ++i)
    {
        //loop-code
    }
}

因此使用该解决方案我可以减少易失性读取,但我会在关闭后将最大循环迭代次数从 1 增加到 100。

该解决方案减少了易失性访问,但没有完全消除它。

您关于易失性读取总是命中主内存的假设不适用于高速缓存一致的系统。易失性读取应该命中 L1,直到另一个线程修改标志并使变量所在的高速缓存行无效。

但是,易失性读取与后续访问建立了先行发生关系,因此这会阻止编译器和 CPU 执行某些延迟隐藏技巧。相反,使用不透明的访问模式来减轻影响(感谢 Holger :))。

像这样应该很快,不过我会把基准测试留给你:

AtomicBoolean active = new AtomicBoolean(true);

while(active.getOpaque())
{
    //loop-code (very fast)
}


//shutdown-thread, called once after a few weeks

active.setOpaque(false);

如果您想知道所有这些访问模式是什么,这里有一个很好的总结:Using JDK 9 Memory Order Modes