C# Singleton Pattern
Singleton Pattern
Singleton Pattern 👤
싱글톤은 애플리케이션이 실행 된 이후 단 한개의 인스턴스만을 생성하고자 할 떄 사용하는 패턴이다.
흔하게 쓰이는 디자인 패턴이며, 주로 환경설정과 같이 하나로 관리할 때 사용한다.
C#에서는 싱글톤을 구현하는 방법이 여러가지가 있는데 이번 포스트에서 확인해보자.
1 - UnsafeSingleton
- 기본적으로 다음과 같이 싱글톤을 구현할 수 있는데 이렇게 구현하게 되면 멀티스레드 환경에서 문제가 발생한다.
두 개 이상의 스레드에서 인스턴스에 접근을 할 때 각기 다른 인스턴스가 생성될 수 있기 때문에 싱글톤에 위반되는 행위가 발생한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class UnsafeSingleton : Singleton
{
private static UnsafeSingleton _instance;
public static UnsafeSingleton Instance
{
get
{
if (_instance is null)
{
_instance = new UnsafeSingleton();
}
return _instance;
}
}
protected UnsafeSingleton() => Console.WriteLine("Create UnsafeSingleton instance!!");
}
2 - SafeSingleton
- 1번은 스레드에 안전하지 않으므로 스레드에 안전하게 구현하면 2번과 같다.
하지만 2번에도 문제가 있으니.. 인스턴스를 참조할 때 마다 lock으로 인해 성능 저하가 발생할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class SafeSingleton : Singleton
{
private static object _thislock = new object();
private static SafeSingleton _instance;
public static SafeSingleton Instance
{
get
{
lock (_thislock)
{
if (_instance is null)
{
_instance = new SafeSingleton();
}
}
return _instance;
}
}
protected SafeSingleton() => Console.WriteLine("Create SafeSingleton instance!!");
}
3 - DCLSingleton
- 2번의 lock으로 인한 성능저하를 막고자 나온 방법이 Double Checked Lock이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Double Checked Locking
class DCLSingleton : Singleton
{
private static object _thislock = new object();
private static DCLSingleton _instance;
public static DCLSingleton Instance
{
get
{
if (_instance is null)
{
lock (_thislock)
{
if (_instance is null)
{
_instance = new DCLSingleton();
}
}
}
return _instance;
}
}
protected DCLSingleton() => Console.WriteLine("Create DCLSingleton instance!!");
}
4 - StaticSingleton
- static constructor을 이용하여 구현할 수도 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
class StaticSingleton : Singleton
{
private static readonly StaticSingleton _instance;
static StaticSingleton()
{
_instance = new StaticSingleton();
}
public static StaticSingleton Instance => _instance;
protected StaticSingleton() => Console.WriteLine("Create StaticSingleton instance!!");
}
5 - LazySingleton
- Lazy를 이용하여 구현할 수도 있는데, Lazy는 즉시 생성이 아닌 접근하려 할 때 생성이 된다.
1
2
3
4
5
6
7
8
class LazySingleton : Singleton
{
private static readonly Lazy<LazySingleton> _instance = new Lazy<LazySingleton>(() => new LazySingleton());
public static LazySingleton Instance => _instance.Value;
protected LazySingleton() => Console.WriteLine("Create LazySingleton instance!!");
}
This post is licensed under CC BY 4.0 by the author.