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/

반응형

+ Recent posts