On Friday, 31 January 2014 at 23:35:25 UTC, Stanislav Blinov
wrote:
// (2)
if (!atomicLoad!(MemoryOrder.raw)(_instantiated))
{
// (1)
synchronized
{ // <- this is 'acquire'
if (_instance is null) {
//(3)
_instance = new AtomicSingleton;
}
} // <- this is 'release'
//(4)
// This store cannot be moved to positions (1) or
(2) because
// of 'synchronized' above
atomicStore!(MemoryOrder.raw)(_instantiated, true);
}
No it's not - the second thread may get to (3)
while some other thread is at (4).
Nope. The only way the thread is going to end up past the null
check is if it's instantiating the singleton. It's inside the
locked region. As long as the bool is false one of the threads
will get inside. the synchronized block, all others will lock.
Once that "first" thread is done, the others will see a non null
reference. No thread can get to 4 until the singleton is
created.
To clarify: only one thread will ever get to position (3). All
others that follow it will see that _instance is not null, thus
will just leave the synchronized section. Of course, this means
that some N threads (that arrived to the synchronized section
before the singleton was created) will all write 'true' into the
flag. No big deal :)