Section 43.3: 스레드-안전한 지연된 Singleton (Double Checked Locking - 이중 검사 잠금 방식)
여기서 소개하고 있는 스레드-안전한 버전의 singleton 은 .NET 초기 버전들에서 필수적이었는데, 이는 당시 정적 (static) 초기화 과정이 스레드-안전함을 보장하지 않았기 때문이다. 이러한 아래와 같은 패턴은 구현 과정에서 실수를 유발할 가능성이 높으므로, 근래의 버전들에서는 정적 초기화 방식의 singleton 사용이 주로 선호된다.
public sealed class ThreadSafeSingleton {
private static volatile ThreadSafeSingleton instance;
private static object lockObject = new Object();
private ThreadSafeSingleton() {}
public static ThreadSafeSingleton Instance {
get {
if (instance == null) {
lock(lockObject) {
if (instance == null) {
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
}
}
눈여겨 볼 부분은 if (instance == null)
로써, 해당 확인 과정이 잠금 (lock) 을 획득하기 전에 한번, 직후에 한번, 총 두번에 걸쳐 등장하고 있다.
첫번째 등장하는 null
확인 과정이 없다고 하더라도 해당 구현은 여전히 스레드-안전할 것이나, 이는 해당 인스턴스를 요청할 때마다 매번 잠금을 획득하여야 하며, 그로 인해 성능 저하가 발생할 수 있다는것을 의미한다. 첫번째 null
확인 과정이 추가됨으로써, 꼭 필요하지 않은 경우에는 잠금을 획득하지 않도록 할 수 있다. 두번째 null
확인 과정은 잠금을 획득한 첫번째 스레드 하나만이 인스턴스 생성을 수행할 수 있음을 보장해 준다. 이후의 스레드들은 잠금을 획득한다고 하더라도 인스턴스가 이미 생성되었음을 확인할 수 있으므로 그 다음에 위치한 생성 코드를 수행하지 않을 것이다.
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.
[출처] https://books.goalkicker.com/CSharpBook/
반응형
'번역 > C# Notes for Professionals' 카테고리의 다른 글
44.1: C# 과 ASP.NET 에서 Unity 를 통한 Dependency Injection 사용하기 (0) | 2022.07.25 |
---|---|
43.4: 지연된, 스레드-안전한 Singleton (.NET 3.5 나 이전 버전들을 위한 대체 구현) (0) | 2022.07.25 |
43.2: Lazy<T> 를 이용한 지연된 (lazy) 방식의 스레드-안전한 Singleton (0) | 2022.05.19 |
43.1: 정적 (static) 초기화 방식의 Singleton (0) | 2022.05.19 |
42.3: Static 키워드 (0) | 2022.05.19 |