싱글턴 패턴이란

  • 전역 변수를 사용하지 않고 객체를 하나만 생성 하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴
  • 역할이 수행하는 작업
    • Singleton
      • 클래스에 instance라는 멤버변수를 선언하고, 생성자를 private로 선언하여 외부에 노출이 되지 않도록 합니다. 이후에 Static으로 전역에서 접근이 가능한 메소드를 생성해서 인스턴스를 반환합니다. 이 때 멤버변수에 이미 변수가 생성이 되어 있다면 해당 인스턴스를 리턴하며, 만약 인스턴스가 한번도 초기화 되지 않았다면, 생성해서 리턴합니다.

 

참고

 

  • 생성(Creational) 패턴
    • 객체 생성에 관련된 패턴
    • 객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공한다.

 

문제점

 

다중 스레드에서 클래스를 이용할 때 인스턴스가 1개 이상 생성되는 경우가 발생할 수 있음.

  • 경합 조건(Race Condition)을 발생시키는 경우
    1. 인스턴스가 아직 생성되지 않았을 때 스레드1이 if문을 실행해 이미 인스턴스가 생성되었는지 확인한다.
    2. 만약 스레드 1이 생성자를 호출해 인스턴스를 만들기 전 스레드 2가 if문을 실행해 싱글톤 변수가 null인지 확인한다.  현재 싱글톤 변수는 null이므로 인스턴스를 생성하는 생성자를 호출하는 코드를 실행하게 된다.
    3. 스레드 1도 스레드 2와 마찬가지로 인스턴스를 생성하는 코드를 실행하게 되면 2개의 클래스 인스턴스가 생성되게 된다.
  • 경합 조건이란?
    • 메모리와 같은 동일한 자원을 2개 이상의 스레드가 이용하려고 경합하는 현상

 

해결책

 

  • 다중 스레드 애플리케이션에서 발생하는 문제를 해결하는 방법

    1. 정적 변수에 인스턴스를 만들어 바로 초기화하는 방법

    2. 인스턴스를 만드는 메소드에 동기화하는 방법

 

멀티스레드에 안전하지 않은 싱글톤 패턴

 

public class Singleton

{

   private static Singleton instance;

 

   private Singleton() {}

 

   public static Singleton Instance

   {

      get 

      {

         if (instance == null)

         {

            instance = new Singleton();

         }

         return instance;

      }

   }

}

 

 

멀티스레드에 안전한 싱글톤 패턴

 

public sealed class Singleton

{

    private static Singleton instance = null;

    private static readonly object padlock = new object();

 

    Singleton() {}

 

    public static Singleton Instance

    {

        get

        {

            lock (padlock)

            {

                if (instance == null)

                {

                    instance = new Singleton();

                }

                return instance;

            }

        }

    }

}

'프로그래밍 > 디자인 패턴' 카테고리의 다른 글

팩토리 패턴 (Factory Pattern)  (0) 2020.02.17
디자인 패턴의 종류  (0) 2020.02.17
디자인 패턴의 개념과 구조  (0) 2020.02.17