[디자인 패턴] 싱글톤 패턴 (Singleton Pattern)

oy Hong·2024년 4월 13일

기술

목록 보기
13/23

싱글톤 (Singleton Pattern)

싱글턴은 같은 종류의 객체가 하나만 존재하도록 하고, 해당 객체에 대한 단일 접근 지점을 제공하는 생성 디자인 패턴이다.


장점

  • 메모리에 한번만 올라가기 때문에 여러 인스턴스의 생성을 통한 메모리 사용을 막을 수 있다.
  • 전역으로 메모리에 올라가기에 다른 인스턴스들에서도 자유롭게 접근이 가능하다.

단점

  • 계속 메모리에 올라가 있기에 사용하지 않을 때도 메모리를 점유한다.
  • 멀티스레드 환경에서의 동기화 처리에 대한 문제가 있다.

기본 싱글톤 예시

public sealed class Singleton
{
  private Singleton() { }

  private static Singleton _instance;

  public static Singleton GetInstance()
  {
    if (_instance == null)
    {
    	_instance = new Singleton();
    }
    return _instance;
  }

  public void someBusinessLogic()
  {
  	// ...
  }
}

class Program
{
  static void Main(string[] args)
  {
    Singleton s1 = Singleton.GetInstance();
    Singleton s2 = Singleton.GetInstance();

    if (s1 == s2)
    {
    	Console.WriteLine("Singleton works, both variables contain the same instance.");
    }
    else
    {
    	Console.WriteLine("Singleton failed, variables contain different instances.");
    }
  }
}

출력
Singleton works, both variables contain the same instance.


스레드로부터 안전한 싱글톤 예시

	class Singleton
    {
        private Singleton() { }

        private static Singleton _instance;

        private static readonly object _lock = new object();

        public static Singleton GetInstance(string value)
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new Singleton();
                        _instance.Value = value;
                    }
                }
            }
            return _instance;
        }

        public string Value { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(
                "{0}\n{1}\n\n{2}\n",
                "If you see the same value, then singleton was reused (yay!)",
                "If you see different values, then 2 singletons were created (booo!!)",
                "RESULT:"
            );
            
            Thread process1 = new Thread(() =>
            {
                TestSingleton("FOO");
            });
            Thread process2 = new Thread(() =>
            {
                TestSingleton("BAR");
            });
            
            process1.Start();
            process2.Start();
            
            // Join(): 
            // 현재 스레드 객체의 작업이 완료되거나 종료될 때까지 기본 스레드의 실행을 대기
            process1.Join();
            process2.Join();
        }
        
        public static void TestSingleton(string value)
        {
            Singleton singleton = Singleton.GetInstance(value);
            Console.WriteLine(singleton.Value);
        } 
    }

출력
FOO
FOO

0개의 댓글