/// <summary> /// Get the thread-safe singleton object. /// </summary> /// <returns></returns> public static SingletonWithDoubleCheckLocking GetInstance() //Lazy initialization. { if (_instance.zzIsNull()) { lock (_syncRoot) //Double-Check Locking { if (_instance.zzIsNull()) { _instance = new SingletonWithDoubleCheckLocking(); } } } return(_instance); }
static SingletonWithDoubleCheckLocking() //The CLR guarantees that the static constructor will be invoked only once for the entire lifetime of the application domain. { _syncRoot = new Object(); _instance = null; }
public SingletonWithDoubleCheckLocking GetSingleton() { if (_value != null) { return _value; } Monitor.Enter(Lock); if (_value == null) { var tmp = new SingletonWithDoubleCheckLocking(); // тут может возникнуть ошибка, если инициализировать // _value сразу. Конструктор объекта не успеет отработать, но // ссылка на него уже будет присвоена переменной // в результате, если поток обратится к синглтону, ссылка на него // не будет null, и поток получит некорректный объект // конструкция Volatile гарантирует, что изменения переменной // будут осуществлены до использования Volatile.Write(ref _value, tmp); // с другой стороны, можно пометить поле _value как волатильное, но // это ненужные потери времени при каждом чтении созданного экземпляра } Monitor.Exit(Lock); return _value; }