简体   繁体   English

Java:在没有 volatile 变量的情况下关闭?

[英]Java: Shutdown without a volatile variable?

Following scenario:以下场景:

I have a application, which runs for weeks and then i want to shut it down gracefully.我有一个应用程序,它运行了数周,然后我想优雅地关闭它。

The following code do the trick:以下代码可以解决问题:

Main-Thread:

boolean volatile active=true;

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


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

active=false;

So now after each loop-iteration, i have a look up in the main memory, cause of that volatile read (right?!).所以现在每次循环迭代后,我都会在主内存中查找,这是易失性读取的原因(对吧?!)。

And i dont want that, only for that shutdown after a few weeks.我不想要那个,只是为了几周后的关机。

Are there any other solution, that my main-thread get notified about that shutdown?有没有其他解决方案,我的主线程会收到有关关闭的通知?

Any signal that goes directly into the main-thread-cache?任何直接进入主线程缓存的信号? so that it dont have to look-up itself in the main memory each time, but get notified from extern?这样它就不必每次都在主内存中查找自己,而是从外部得到通知?

Or any other solution?还是有其他解决办法?

Edit (integrate my own answer into this question):编辑(将我自己的答案整合到这个问题中):

a possible solution could be, reducing the volatile access, see the following code:一个可能的解决方案是,减少易失性访问,请参阅以下代码:

boolean volatile active=true;


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

so with that solution i can reduce the volatile reads, but i increase, after a shutdown the max loop-iterations from 1 to 100.因此,使用该解决方案,我可以减少易失性读取,但在关闭后,我将最大循环迭代次数从 1 增加到 100。

that solution decrease the volatile access, but dont eliminate it fully.该解决方案减少了易失性访问,但并没有完全消除它。

Your assumption that a volatile read always hits main memory doesn't hold for cache-coherent systems.您认为易失性读取始终命中主内存的假设不适用于缓存一致性系统。 The volatile read should hit L1 until the other thread modifies the flag and invalidates the cacheline upon which the variable resides.易失性读取应该命中 L1,直到另一个线程修改标志并使变量所在的缓存行无效。

However, volatile reads establish a happens-before relation with subsequent accesses, so this prevents the compiler and CPU from performing certain latency-hiding tricks.但是,易失性读取与后续访问建立了先发生关系,因此这可以防止编译器和 CPU 执行某些延迟隐藏技巧。 Instead, use opaque access mode to lessen the impact (thanks Holger :)).相反,使用不透明访问模式来减轻影响(感谢 Holger :))。

Something like this should be fast, though I'll leave the benchmarking up to you:像这样的事情应该很快,但我会将基准测试留给您:

AtomicBoolean active = new AtomicBoolean(true);

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


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

active.setOpaque(false);

If you're wondering what all these access modes are, here's a nice summary: Using JDK 9 Memory Order Modes .如果您想知道所有这些访问模式是什么,这里有一个很好的总结:使用 JDK 9 内存顺序模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM