장발의 개발러

[J2SE] 싱클톤(sigletone) 패턴 본문

개발이즈 마이라이프/JavaSE

[J2SE] 싱클톤(sigletone) 패턴

장발의 개발러 2012. 2. 23. 11:45

출처: 싱클톤 패턴 만들기

*참고문헌: Head First Design Pattern

1 싱글턴 패턴(Singletone pattern)이란
: 특정 클래스에 대해서 객체 인스턴스가 하나만 만들어질 수 있도록 해 주는 패턴

2 사용 용도
: 캐시, 대화상자, 사용자 설정, 레지스트리 설정 처리 객체, 로그 기록용 객체, 드바이스 드라이버 등

3 기본적인 싱글턴 패턴 구현 예
코드보기 
 1) private static Singleton uniqueInstance
  : Singleton 클래스의 유일한 인스턴스를 저장하기 위한 static 변수
 2) private Singleton() {}
  : Singletone 클래스의 생성자 선언을 private로 했기 때문에 클래스 외부에서 클래스 인스턴스 생성 불가능!
 3) public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
  : uniqueInstance를 리턴, 이때 uniqueInstance가 null이면 Singletone 클래스의 인스턴스를 생성해서 리턴

* 하지만 getInstance() 함수는 두 개 이상의 스레드가 동시에 실행될 경우 문제가 생길 수 있음!!


4 멀티스레딩 문제 해결 방법 예
: 간단하게 getInstance()에 synchronized를 붙여서 getInstance()를 동기화시키면 해결됨.
코드보기 

* 하지만 동기화를 하려면 속도 이슈가 발생함!!


5 동기화하지 않고 멀티스레딩 문제 해결 방법 예
 1) 처음부터 인스턴스를 생성하기
코드보기 
public class Singleton {
    private static Singleton uniqueInstance = new Singleton();
    
    private Singleton() {}
    
    public static synchronized Singleton getInstance() {
        return uniqueInstance;
    }
}
 
 2) DCL(Double-Checking Locking) 사용하기
  : DCL을 사용하면 일단 인스턴스가 생성되어 있는지 확인한 다음, 생성되어 있지 않았을 때만 동기화를 할 수 있음. 또한 volatile 키워드를 사용하면 멀티스레딩을 쓰더라도 uniqueInstance 변수가 Singleton 인스턴스로 초기화되는 과정이 올바르게 진행됨
(단, DCL은 자바 1.4 이전 버전에서는 쓸 수 없음!)
코드보기 
public class Singleton {
    private volatile static Singleton uniqueInstance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}