Мне кажется, что с блокировками или без блокировок (на сеттере) у вас всегда будет проблема синхронизации. Представьте себе эти сценарии:
- У вас есть блокировка на установщике, но вызов получателю поступает как раз перед тем, как блокировка включена. Вызывающий получает старый экземпляр.
- У вас есть блокировка на установщике, но вызов получателю поступает сразу после того, как блокировка включена. Вызывающая сторона ожидает освобождения блокировки, а затем получает новый экземпляр.
- У вас нет блокировки на сеттер, и вызов поступает только за до того, как вы замените экземпляр. Вызывающий получает старый экземпляр.
- У вас нет блокировки на сеттер, и вызов приходит только через после , когда вы заменяете экземпляр. Вызывающая сторона получает новый экземпляр.
С блокировками и без блокировок зависит, какой момент времени получатель получает.
Единственная проблема, которую я вижу, это если вы хотите установить Instance
в null
. Если это так, ваш текущий код не будет работать, потому что _instance
может быть изменено между оператором if
и его возвратом. Вы можете решить эту проблему, взяв копию ссылки:
public static MyClass Instance
{
get
{
var instanceSafeRef = _instance;
if(instanceSafeRef == null)
{
lock(_padlock)
{
if(_instance == null)
{
_instance = new MyClass();
}
instanceSafeRef = _instance;
}
}
return instanceSafeRef;
}
set => _instance = value;
}