public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
싱글톤 패턴의 정의
싱글턴 패턴은 클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공
싱글턴 패턴을 실제로 적용할 때는 클래스에서 하나뿐인 인스턴스를 관리하도록 만들기
그리고 다른 어떤 클래스에서도 자신의 인스턴스를 추가로 만들지 못하게 하기
어디서든 그 인스턴스에 접근할 수 있도록 전역 접근 지점 제공
언제든 이 인스턴스가 필요하면 클래스에 요청할 수 있게 만들어 놓고 요청이 들어오면 하나뿐인 인스턴스 건네주도록 만들기
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
} // 게으른 방식으로 생성 요청이 들어오면 하나뿐인 인스턴스를 건네주도록 만들기

다음과 같이 멀티스레드 환경시 인스턴스가 여러개 생기는 문제가 발생
public class Singleton{
private static Singleton uniqueInsance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
getInstance()에 synchronized 키워드만 추가하면 한 스레드가 메소드 사용을 끝내기 전까지 다른 스레드는 기다려야한다.
허나 동기화 할때 속도 문제 발생
동기화가 필요한 시점은 이 메소드가 시작되는 때뿐 uniqueInstance 변수에 Singleton 인스턴스를 대입하면 굳이 이 메소드를 동기화된 상태로 유지할 필요가 없음
처음을 제외하면 동기화는 불필요한 오버헤드만 증가
허나 getInstance() 의 속도가 그리 중요하지 않다면 그냥 냅두기
public class Singleton{
private static Singleton uniqueInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance;
}
}
다음과 같은 방식은 JVM 에서 Singleton 의 하나뿐인 인스턴스를 생성
JVM에서 하나뿐인 인스턴스를 생성하기 전까지 그 어떤 스레드도 uniqueInstance 정적 변수에 접근 할 수 없다
DCL(Double-Checked 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 = nuew Singleton();
}
}
}
return uniqueInstance;
}
}
인스턴스가 있는지 확인하고 없으면 동기화된 블록으로 들어가기
처음에만 동기화후
블록에서 다시 한번 변수가 null 인지 확인한 다음 인스턴스 생성
volatile 키워드를 사용하면 멀티스레딩을 쓰더라도 uniqueInstance 변수가 Singleton 인스턴스로 초기화되는 과정이 올바르게 진행
enum 으로 싱글톤 생성해서 해결시 동기화 문제 클래스 로딩 문제 , 리플렉션, 직렬화 , 역직렬화 문제등 해결 가능
public enum Singleton{
UNIQUE_INSTNACE;
}
public class SingletonClient{
public static void main(String[] args){
Singleton singleton = Singleton.UNIQUE_INSTANCE;
}
}
다시한번
싱글톤패턴은 클래스 인스턴스를 하나만 만들고 그 인스턴스로 전역 접근 제공하기