싱글턴 패턴이란?
인스턴스가 하나 뿐인 특별한 객체를 만들 수 있게 해주는 패턴!
어디서드지 그 인스턴스에 접근 할 수 있도록 하기 위한 패턴
어떤 용도일때 쓰는가?
객체 중 하나만 있으면 되는 경우,
예를 들어 스레드 풀, 캐시, 대화상자, 사용자 설정 혹은 레지스토리 설정을 처리하는 객체, 로그 기록용 객체, 프린터나 그래픽 카드 같은 디바이스를 위한 디바이스 드라이버 같은 것
위에 적은 객체들이 두개 이상 생기는경우, 오류가 생기거나 ,자원을 불 필요하게 사용 할 수 있음
왜, 근데 싱글턴 패턴을 써야하는가?
해당 클래스의 인스턴스는 하나만 만든다라는 관행 혹은 전역변수로 하면 되지 않을까?
>> 싱글턴 패턴은 특정 클래스에 대해서 객체 인스턴스가 하나만 만들어 질수 있도록 해주는 패턴,
해당 패턴 사용시 전역변수를 사용할때처럼 객체 인스턴스를 어디서든지 액세스 할 수 있음,
또한 전역변수 쓸때 처럼 여러 단점 감수하지 않아도 됨
* 전역변수의 단점 : 전역변수에 객체 대입시, 어플리케이션 시작할때 객체 생성되어짐, 이때 해당 객체가 자원을 많이 사용한다로 가정해볼때, 해당 객체를 한번도 사용하지 않는다면 자원만 잡아먹는 쓸모없는객체로 변화되어짐
<-> 싱글톤은 필요할 때만 객체를 만들 수 있음!
* 플랫폼마다 다를 수 있음, 어떤 JVM에서는 객체를 나중에 필요할때 생성하기도 함
싱글턴 패턴 내에 하나뿐의 객체라고 알수 있는 이유?
new 인스턴스 사용해서 언제든지 새로운 인스턴스를 만들면 되는 것이 아닌가?
public으로 지정된 생성자가 없고 private으로 지정되어 있음
그래서 싱글턴 객체가 필요할 경우 인스턴스를 직접 만드는 것이 아닌, 인스턴스를 달라고 요청을 해야함
싱글턴 클래스내에는 해당 용도로 사용하기 위한 정적메소드를 생성 함
- 싱글톤 클래스 다이어 그램
Singleton |
static uniqueInstance //기타데이터... |
static getInstance() //기타 메소드... |
* uniqueInstance : 클래스 변수에 싱글턴의 유일무이 한 인스턴스 저장
* getInstance() : 정적 메소드, 언제어디서든지 메소드 호출 할 수 있음
싱글톤 클래스는 일반적인 클래스처럼, 다양한 데이터와 메소드를 사용할 수 있음
스레드가 추가 되었을때에 대해서 해결 법
public static synchronize Singletone getInstance() --> synchronize 키워드 추가
synchronize의 역할 : 하나의 스레드가 메소드 사용을 끝내기 전 까지 다른 스레드에서는 기다려야함
두개이상의 스레드가 동시에 메소드를 실행 시키는 일이 일어나지 않음
동기화를 하게되면 속도에 문제가 생김
해결법?
- getInstance()의 속도가 중요하지 않으면 그냥 둠 , 큰 부담을 주지 않는다면 그냥 나둬도 됨, 단 동기화하면 성능이 100배 정도 저하가 된다.! 해당 메소드가 병목으로 작용하면 다른방법 생각해야함
- 인스턴스를 필요할 대 생성하지 말고 처음부터 만들어둠, 실행중에 수시로 만들고 관리하기가 성가시다면 하단과 같이 만드는 것도 괜찮은 방법
public class Singleton {
private static Singleton uniqueInstance = new Singleton(); # 정적 초기화 부분에서 인스턴스를 생성함
private Singletone() {}
public static Singleton getInstance(){
return uniqueInstance; #인스턴스가 이미 있으니 리턴만 함
}
}
- DCL을 사용하여 getInstance에서 동기화 되는 부분을 줄임
DCL 사용시 인스턴스가 생성되어 있는지 확인한 다음, 생성되어 있지 않을때만 동기화 할 수 있게 함
=> 처음에만 동기화하고 나중에는 동기화 하지 않아도 됨
public static volatile Singletone getInstance() --> volatile 키워드 추가
* volatile 사용시 멀티 스레딩 사용하더라도, uniqueInstance 변수가 Singleton 인스턴스로 초기화 되는 과정이 올바르게 진행됨
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singletone() {}
public static Singleton getInstance(){
if( uniqueInstanc == null){ #인스턴스 있는지 확인하고 없으면 동기화된 블럭으로 들어감
sycnhronized (Singleton.class){ #처음에만 동기화 됩니다
if( uniqueInstanc == null){ #다시한번 변수가 null인지 확인하고 다음 인스턴스 생성
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
*DCL은 자바 1.4 이전버전에서는 사용할 수 없음..
'IT > Etc.' 카테고리의 다른 글
[개념] 페이로드(Payload)란? (0) | 2022.05.18 |
---|---|
[디자인패턴] 데코레이터 패턴 (0) | 2021.01.22 |
[디자인 패턴] 옵저버 패턴 Observer Pattern (0) | 2021.01.15 |
[디자인패턴] 디자인 패턴이 중요할까? (0) | 2021.01.15 |
디자인패턴 (0) | 2021.01.15 |