보통 멀티 쓰레드 환경에서 한 개의 객체만 가지고 사용하려고 할 때
쓰는 디자인 패턴 입니다.
하나의 클래스에 대해서 재생성 (new) 하지 않고 재활용만 하는 것이죠
보통 사용 방법은
ExecutorServiceThreadPoolStore executorServiceThreadPoolStore
= ExecutorServiceThreadPoolStore.getInstance();
이렇게 해서 getInstance 메소드의 return 값으로 받아내는 방법인데
자주 쓰이는 패턴입니다.
저는 디자인 패턴 중에 가장 많이 사용하게 되는 패턴이더군요.
여기에 맹점이 있는데
Singletern Pattern 에 대해서 인터넷을 찾아보면 쓰레드에 대해
안전하지 않게 엉뚱한 코드를 만들어서 보여주고 계신 분들이 계십니다.
예를 들면
public class ExecutorServiceThreadPoolStore {
private static ExecutorServiceThreadPoolStore executorServiceThreadPoolStore;
private static ExecutorService executor;
private ExecutorServiceThreadPoolStore(){
executor = Executors.newFixedThreadPool(100);
}
public static ExecutorServiceThreadPoolStore getInstance(){
if(executorServiceThreadPoolStore == null){executorServiceThreadPoolStore = new ExecutorServiceThreadPoolStore();
}
return executorServiceThreadPoolStore;
}
public ExecutorService getExecutorService(){return executor;
}
}
라는 방식의 코드 로서 문제가 되는 부분은
if(executorServiceThreadPoolStore == null){
...
}
부분 입니다.
왜 문제가 되는가 하면 멀티 쓰레드 형식의 Application 일 때
if(executorServiceThreadPoolStore == null){
의 if 문 안에 2개 이상의 쓰레드가 동시에 들어와 버리게 된다면
그 때 마다 new 하여 ExecutorServiceThreadPoolStore 객체를
생성하게 될 것이기 때문입니다.
그래서 위의 코드는
public class ExecutorServiceThreadPoolStore {
private static ExecutorServiceThreadPoolStore executorServiceThreadPoolStore = new ExecutorServiceThreadPoolStore();
private static ExecutorService executor;
private ExecutorServiceThreadPoolStore(){
executor = Executors.newFixedThreadPool(100);
}
public static ExecutorServiceThreadPoolStore getInstance(){
return executorServiceThreadPoolStore;
}
}
와 같이 변경 되어야 합니다.
이렇게 하여야 객체가 재생성 되지 않는 쓰레드에 안전한 코드가 됩니다.
===================================================
최근에 singleton 관련 코드를 보니 Scot Floess 라는 분 께서 아래와 같은
singleton code 를 만들어서 이 code에 대한 스크랩이 많았습니다.
code 를 본 순간 진짜 감탄에... 과연 내가 이렇게 code 를 짤 수 있을 것인가
라는 회의가 들더군요. 현인들께 감사하는 마음을 가져야겠습니다.
최근 source code 중에 가장 충격 받은 code 인 것 같습니다.
public class Singleton {
private Singleton(){
}
//static inner class 와 final 키워드를 사용하여 처음 한번만 생성되도록 한다.
private static final class SingletonHolder{
static final Singleton singleton = new Singleton();
}
//inner class 를 통하여 instance 를 반환하도록 한
public static Singleton getInstance(){
return SingletonHolder.singleton;
}
}
'JAVA' 카테고리의 다른 글
[ JAVA ] System.getProperty("file.encoding") 변경 방법 (0) | 2013.03.12 |
---|---|
[ JAVA ] Iterator Pattern ( iterator 패턴 ) (0) | 2013.02.18 |
[ JAVA ] 일본어 파일 읽기 (0) | 2013.01.29 |
Illegal constant pool type 에러 (0) | 2013.01.18 |
[ JAVA ] 숫자 인지 아닌지 확인 ( isNaN ) (0) | 2012.11.24 |
댓글