01-Feb-2014 18:23, Stanislav Blinov пишет:
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 :)
Yes, I see there could be many writes to _instantiated field but not
_instance.
--
Dmitry Olshansky