有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

并发Java:在没有可变变量的情况下关闭?

以下场景:

我有一个应用程序,运行了几个星期,然后我想优雅地关闭它

下面的代码实现了这一点:

Main-Thread:

boolean volatile active=true;

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


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

active=false;

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

我不想这样,只是为了几周后的关闭

有没有其他解决方案,让我的主线程得到关于关闭的通知

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

还是其他解决方案

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

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

boolean volatile active=true;


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

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

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


共 (1) 个答案

  1. # 1 楼答案

    对于缓存一致性系统,您认为易失性读取总是命中主内存的假设并不成立。volatile读取应该命中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