以下情况:
我有一个应用程序,它可以运行数周,然后我要正常关闭它。
以下代码可以解决问题:
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。