싱글톤 패턴의 정의 -
싱글톤 패턴은 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴입니다.
* 고전적인 싱글톤 패턴 구현법
public class Singleton{
private static SingleTon uniqueInstance;
private Singleton() {}
public static Singleton getInstance(){
if(uniqueInstance == null){
unuqueInstance = new Singleton();
}
return uniqueInstance;
}
}
위 코드는 얼핏보기에 싱글톤 패턴을 정확히(안전히) 구현한 것 같지만 멀티 스레드 환경에서 실행하였을 때 문제점이 발생합니다.
getInstance()메소드가 끝나기도 전에 각각의 스레드들이 접근하기 때문에
유일한 인스턴스생성을 보장할 수 없습니다.
간략히 설명드리자면,
스레드1번이 if(uniqueInstance == null) 을 체크합니다. -> null입니다. 아직 인스턴스 생성 하기 전이니까요.
다음 스레드 2번이 if(uniqueInstance == null) 을 체크합니다. -> 역시 null입니다. 아직 인스턴스 생성 하기 전이니까요.
스레드 1번이 인스턴스를 생성합니다.
스레드 2번이 인스턴스를 생성합니다.
이런, 상황이 좋지 않군요 .
고전적인 싱글톤 패턴으로 구현하였을 경우, 멀티 스레드 환경에서 유일한 인스턴스생성을
보장할 수 없습니다.
멀티스레딩 문제 해결방법
getInstance()를 동기화시키기만 하면 멀티스레딩과 관련된 문제가 간단하게 해결됩니다.
public static Singleton getInstance()
-> public static synchronized Singleton getInstance()
질문 : 이렇게 하면 문제가 해결되긴 하겠지만, 동기화를 하면 속도 문제가 생기지 않나요?
답 : 좋은 지적입니다. 사실 동기화가 꼭 필요한 시점은 이 메소드가 시작되는 때 뿐입니다. 바꿔 말하자면, 일단 uniqueInstance 변수에 Singleton 인스턴스를 대입하고 나면 굳이 이 메소드를 동기화된 상태로 유지시킬 필요가 없는것입니다. 첫 번째 과정을 제외하면 동기화는 불필요한 오버헤드만 증가시킬 뿐 입니다.
더 효율적인 방법
1. 애플리케이션에서 반드시 Singleton의 인스턴스를 생성하고, 그 인스턴스를 항상 사용한다면, 또는 인스턴스를 실행중에 수시로 만들고 관리하기가 성가시다면 다음과 같은 식으로 처음부터 Singleton인스턴스를 만들어버리는 것도 괜찮은 방법입니다.
public class Singleton{
private static SingleTon uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance(){
return uniqueInstance;
}
2. DCL(Double-Checking Locking)을 써서 getInstance()에서 동기화되는 부분을 줄입니다.
DCL(Double-Checking Locking)을 사용하면, 일단 인스턴스가 생성되어 있는지 확인한 다음, 생성되어있지 않았을 때만 동기화를 할 수 있습니다. 이렇게 하면 처음에만 동기화를 하고 나중에는 동기화를 하지 않아도 됩니다.
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;
}
}
'Java' 카테고리의 다른 글
[Java] GIF 이미지 생성 (0) | 2009.12.22 |
---|---|
[Java] 원격디버깅 (0) | 2009.11.25 |
[Java] Java관련 무료동영상 강의 (0) | 2009.09.23 |
[Java] 배열내 중복값 제거 - java.util.TreeSet (0) | 2009.09.18 |
[Java] Pass by Value (0) | 2009.07.06 |