Здравствуйте, alexkro, Вы писали:
A>Допустим, делается так как ты предлагаешь. Тогда есть следующий вариант развития событий: первый поток входит в lock выделяет Singleton и инициализирует Singleton.value, но замещается вторым потоком прям перед вызовом MemoryBarrier(). Второй поток проверяет Singleton.value, его значение уже не null, и оно тут-же возвращается из функции. Далее второй поток пытается использовать тот объект Singleton, который он получил, но так как сконструированный объект Singleton еще находится в кэше первого потока (пусть эти потоки выполняются на разных процессорах), то второй поток, думая, что он обращается к памяти Singleton'а, на самом деле читает память, в которой еще мусор. Вот так.
почему мусор? ИМХО, там должен быть 0 — поскольку сброс кэша еще не выполнен, а Singleton.value тоже находится в нем
а в оригинальном варианте есть немаленькая вероятность, что будет выделено несколько объектов singleton (по одному на каждый процессор

)