Search Results for '싱글턴'

1 POSTS

  1. 2008/12/28 싱글턴과 동기화 (4)

싱글턴과 동기화

2008/12/28 15:15

싱글턴을 구현하다가, Head First Design Patterns에서 싱글턴에 관한 문제점을 읽었던 기억이 나서, 책을 뒤적여봤다. 일반적으로 Singleton은 다음과 같이 구현한다.

public class Singleton {
	private static Singleton uniqueInstance;
	// 기타 인스턴스 변수..
	private Singleton() {}
	public static Singleton getInstance() {
		if (unuqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
	// 기타 메소드..
}

하지만, 위 방법은 멀티쓰레딩에서 문제점이 있다. if문 안쪽 부분이 동기화가 되지 않으면, 인스턴스가 두개 이상 생성될 수 있다. 가장 간단한 해결책은 getInstance를 synchronized로 선언하는 것이지만, 속도가 수십배 느려질 수 있다. (책의 주장에는 메소드를 통째로 동기화하면, 100배까지 느려질 수도 있다고 한다.)

세가지 해결책이 있다.

  1. getInstance()의 속도가 그리 중요하지 않으면, 그냥 synchronized로 한다.
  2. 인스턴스를 lazy binding을 하지 말고, 처음부터 만든다.
  3. DCL(Double Checking Locking)을 써서 동기화 되는 부분을 줄인다.

2번은 그냥 위 코드에서, uniqueInstance를 선언할 때에 인스턴스를 생성하란 소리다.

public class Singleton {
	private static Singleton uniqueInstance = new Singleton();
	// 생략..

책임을 JVM에게 넘기게 되고, 코드는 가장 깔끔하긴 한데, 일단 사용되지 전에도 인스턴스를 차지하고 있고, 몇몇 문제들이 있다고 한다. 다음은 DCL을 쓰는 방법.

public class Singleton {
	private volatile static Singleton uniqueInstance;
	// 기타 인스턴스 변수..
	private Singleton() {}
	public static Singleton getInstance() {
		if (unuqueInstance == null) {
			synchronized (Singleton.class) {
				if (unuqueInstance == null) {
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
	// 기타 메소드..
}

당연하지만, 안쪽의 if문을 없애면 안된다. 인스턴스가 두개 이상 생성될 수 있다. 그래서 Double Checking이다. 반면, 성능은 1번에 비해서 빠르고, 2번의 단점도 없다. 타이핑 하기 좀 귀찮다는 것 정도? =_=;

1~3번 중에 입맛대로 골라쓰면 되겠다. 코드의 출처는 Head First Design Patterns이다.