Singleton: Difference between revisions
Content added Content deleted
(→{{header|Python}}: - actual singleton implementation in Python) |
(Provided 5 C# implementations.) |
||
Line 314: | Line 314: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
===First attempt at thread-safety using locking.=== |
|||
A thread safe singleton implementation. |
|||
Performance suffers because the lock is acquired every time Instance is accessed.<br /> |
|||
To make it non-thread safe remove lockObject and the lock() statement. |
|||
This implementation is extremely slow and should not be used (but is seen often). |
|||
<lang csharp>// Usage: Singleton.Instance.SomeMethod() |
|||
<lang csharp>public sealed class Singleton1 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes |
|||
class Singleton |
|||
{ |
{ |
||
private static Singleton1 instance; |
|||
private static readonly object lockObj = new object(); |
|||
private Singleton() {} |
|||
public static Singleton1 Instance { |
|||
{ |
get { |
||
lock(lockObj) { |
|||
{ |
if (instance == null) { |
||
instance = new Singleton1(); |
|||
⚫ | |||
⚫ | |||
⚫ | |||
} |
} |
||
⚫ | |||
} |
} |
||
⚫ | |||
} |
} |
||
} |
|||
// The rest of the methods |
|||
}</lang> |
|||
===Fixes excessive locking by double-checking for null.=== |
|||
Still uses locking and implementation is ugly and verbose. |
|||
<lang csharp>public sealed class Singleton2 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes, but only once |
|||
{ |
|||
private static Singleton2 instance; |
|||
private static readonly object lockObj = new object(); |
|||
public static Singleton2 Instance { |
|||
get { |
|||
if (instance == null) { |
|||
lock(lockObj) { |
|||
⚫ | |||
⚫ | |||
} |
|||
⚫ | |||
} |
|||
return instance; |
|||
} |
|||
} |
|||
}</lang> |
|||
===Really simple implementation without locking.=== |
|||
It still is not completely lazy. If there are other static members, accessing any of those will still cause initialization. |
|||
<lang csharp>public sealed class Singleton3 //Lazy: Yes, but not completely ||| Thread-safe: Yes ||| Uses locking: No |
|||
{ |
|||
private static Singleton3 Instance { get; } = new Singleton3(); |
|||
static Singleton3() { } |
|||
}</lang> |
|||
===Truly lazy by using an inner class.=== |
|||
This version is completely lazy but the code looks more complicated than it needs to be. |
|||
<lang csharp>public sealed class Singleton4 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No |
|||
{ |
|||
public static Singleton4 Instance => SingletonHolder.instance; |
|||
private class SingletonHolder |
|||
{ |
|||
static SingletonHolder() { } |
|||
internal static readonly Singleton4 instance = new Singleton4(); |
|||
} |
|||
}</lang> |
|||
===Using Lazy<T>=== |
|||
C# has a dedicated type for lazy initialization: Lazy<T>.<br /> |
|||
It makes implementing a Singleton really easy. Recommended. |
|||
<lang csharp>public sealed class Singleton5 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No |
|||
{ |
|||
private static readonly Lazy<Singleton5> lazy = new Lazy<Singleton5>(() => new Singleton5()); |
|||
public static Singleton5 Instance => lazy.Value; |
|||
}</lang> |
}</lang> |
||