ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] Singleton Pattern
    Learn/Architecture 2022. 8. 31. 00:38

    # 개요

    인스턴스가 단 하나만 만들어지게 하고싶을 때 사용하는 패턴

     

    (예시) Thread Pool Manager은 여러개면 그들간의 조율이 필요하므로 하나만 있는게 좋다. 

     

    싱글톤은 new로 인스턴스를 생성하는게 아니라 getInstance 함수로 얻는다. 

     

    # 기본 구조

    • 일반적인 생성자와는 달리 접근하지 못하도록 private로 생성자를 만든다. 
      • 생성자를 만들지 않으면 자바가 알아서 public으로 생성하므로 꼭 만들어줘야한다. 
    • 외부에서는 getInstance를 통해서만 인스턴스를 얻을 수 있다.
      • 외부에서 이 함수에 바로 접근할 수 있게 static으로 선언해야 한다. 
      • 생성자를 대신하므로 public으로 열어줘야 한다. 
    • uniqueInstance는 클래스에 단 하나만 있어야 하므로 static으로 만든다. 
      • 외부에서 마음대로 조작하지 못하게 private로 만든다. 
    public class Singleton {
        private static Singleton uniqueInstance;
        
        // other useful instance variables
        
        private Singleton() {} 
        
        public static Singleton getInstance() {
            // 한번만 생성되도록 함
            if (uniqueInstance == null) {       
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
        
        // other useful methods 
    }

     

    # Singleton on Multi-threads

    싱글톤은 멀티 쓰레드에서 잘 작동하지 않는다. 

    • 아래와 같이 타이밍이 엇갈리면 제대로 작동하지 않는다. 

    해결책 1

    getInstance 함수에 synchronized 키워드를 붙여준다. 

    • synchronized 함수는 하나의 쓰레드에서 사용되면 lock이 걸린다. 

    잘 동작하지만 문제는 이렇게 작성하면 성능에 영향을 준다. 

    • 두 번째 쓰레드부터는 딱히 필요가 없다. 

    해결책 2

    아래와 같이 uniqueInstance를 선언해줄 때 인스턴스를 만들어준다. 

     

    성능 문제는 해결되지만 무조건 인스턴스를 만들기 때문에 메모리 사용 측면에서는 좋지 않다. 

    public class Singleton {
        private static Singleton uniqueInstance = new Singleton();
        
        // other useful instance variables
        
        private Singleton() {} 
        
        public static Singleton getInstance() {
            return uniqueInstance;
        }
        
        // other useful methods 
    }

    해결책 3

    자바 1.5부터 volatile이라는 키워드를 제공한다. 

    그리고 getInstance에서는 double-checked locking을 적용한다. 

    public class Singleton {
        private volatile static Singleton uniqueInstance = null;
        
        // other useful instance variables
        
        private Singleton() {} 
        
        public static Singleton getInstance() {
            if (uniqueInstance == null) {
                synchronized(Singleton.class) {
                    if (uniqueInstance == null) 
                        uniqueInstance = new Singleton();
                }
            }
            return uniqueInstance;
        }
        // other useful methods 
    }

     

    # QUIZ

    SingletonA 클래스와 SingletonB 클래스가 각각 싱글톤 패턴으로 구현되었다고 가정할 때, 다음 코드의 수행결과를 쓰시오.

    정답

    각 클래스별로 같은게 나오므로 1, 2가 출력된다. 

     

     

    댓글

Designed by Tistory.