Написать синглтон, с которым можно быстро и безопасно работать из разных потоков, задача не такая уж и тривиальная, как кажется на первый взгляд. С блокировками это делается довольно просто, например, так:
Двойная проверка на null нужна для того, чтобы не делать блокировок без необходимости. А если хочется совсем без блокировок? Изучая исходный код пула массивов от майкрософт, нашел реализацию lockfree синглтона. Вот она, очищенная от лишних деталей самого пула:
public class Singleton
{
private static readonly object syncObj = new object();
private static volatile Singleton instance;
public Singleton Shared()
{
if (instance == null)
{
lock (syncObj)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
private Singleton()
{
}
// ...
}
Двойная проверка на null нужна для того, чтобы не делать блокировок без необходимости. А если хочется совсем без блокировок? Изучая исходный код пула массивов от майкрософт, нашел реализацию lockfree синглтона. Вот она, очищенная от лишних деталей самого пула:
public class Singleton
{
private static Singleton instance= null;
public static Singleton Shared
{
get { return Volatile.Read(ref instance) ?? EnsureSharedCreated(); }
}
private static Singleton EnsureSharedCreated()
{
Interlocked.CompareExchange(ref instance, Create(), null);
return instance;
}
public static Singleton Create()
{
return new Singleton();
}
private Singleton()
{
}
// ...
}