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.
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.
However, volatile reads establish a happens-before relation with subsequent accesses, so this prevents the compiler and CPU from performing certain latency-hiding tricks. Instead, use opaque access mode to lessen the impact (thanks 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.