객체의 인스턴스가 오직 1개만 생성되는 패턴.
최초 한번의 new 연산자를 통해 고정된 메모리 영역을 사용하기 때문에 추후 해당 객체에 접근할 때 메모리 낭비를 방지할 수 있다. 또한 이미 생성된 인스턴스를 활용해 속도 측면에서도 이점이 있다.
싱글톤 인스턴스가 전역으로 사용되기 때문에 다른 클래스의 인스턴스들이 접근하여 사용하기 용이하다. 단, 여러 클래스의 인스턴스에서 싱글톤 인스턴스의 데이터에 동시 접근하면 동시성 문제가 발생할 수 있어서 유의해서 설계해야 한다.
각각의 방식에 공통적으로 갖는 특징이 있다.
public class Singleton {
private static final Singleton instance = new Singleton();
// private constructor to avoid client applications to use constructor
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
싱글톤 클래스의 인스턴스를 클래스 로딩 단계에서 생성하는 방법이다.
하지만 어플리케이션에서 해당 인스턴스를 사용하지 않더라도 인스턴스를 생성하기 때문에 자칫 낭비가 발생할 수 있다.
public class Singleton {
private static Singleton instance;
private Singleton(){}
//static block initialization for exception handling
static{
try{
instance = new Singleton();
}catch(Exception e){
throw new RuntimeException("Exception occured in creating singleton instance");
}
}
public static Singleton getInstance(){
return instance;
}
}
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
public class Singleton {
private Singleton(){}
private static class SingletonHelper{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHelper.INSTANCE;
}
}
public enum EnumSingleton {
INSTANCE;
public static void doSomething(){
//do something
}
}