키보드 리더, 프린터 스풀러, 점수기록표 등 클래스의 객체를 하나만 만들어야 하는 경우 사용한다. 클래스 내에서 인스턴스가 단 하나뿐임을 보장하므로, 프로그램 전역에서 해당 클래스의 인스턴스를 바로 얻을 수 있고, 불필요한 메모리 낭비를 최소화한다.
가장 단순한 싱글톤 구현 방법이지만, 불필요한 객체 생성으로 메모리 비효이 될 수도 있다.
public class Singletone {
// static 선언으로 Class Loader가 로딩될 때 객체로 만들어 버린다.
private static Singletone instance = new Singletone();
private int num = 0;
// private로 하면 할당 못하지.
private Singletone() {}
public static Singletone getSingletone() {
return instance;
}
// num 증가
public void plusNum() {
num++;
}
// get num
public int getNum() {
return num;
}
}
실제 필요할 때 (클래스 호출될때) 인스턴스가 생성되기 때문에 불필요한 메모리 할당을 줄일 수 있다.
하지만 싱글톤 패턴은 여러 곳에서 접근할 수 있기 때문에 Multi-Tread에 안전하지 않다.
public class Singletone {
// 선언만 해주기 때문에 Class Loader가 실행이 되어도 인스턴스 생성이 안된다.
private static Singletone instance;
private int num = 0;
// private로 하면 할당 못하지.
private Singletone() {}
public static Singletone getSingletone() {
// instance가 null(인스턴스 생성)이 안되었다면 생성 후 리턴한다.
if(instance==null) instance = new Singletone();
return instance;
}
}
Tread-Safe를 위해 인스턴스 반환 메소드에 synchronized 걸어준다.
자 이제 Multi-Thread에 안전하다.
하지만! 여러곳에서 참조를 할때 마다 비용이 낮지 않은 Synchronized를 호출하는 비효율이 발생된다.
public class Singletone {
// 선언만 해주기 때문에 Class Loader가 실행이 되어도 인스턴스 생성이 안된다.
private static Singletone instance;
private int num = 0;
// private로 하면 할당 못하지.
private Singletone() {}
public static synchronized Singletone getSingletone() {
// instance가 null(인스턴스 생성)이 안되었다면 생성 후 리턴한다.
if(instance==null) instance = new Singletone();
return instance;
}
}
SingletonHelper 클래스는 Inner Class로 선언되었기 때문에 Singleton 클래스가 Class Loader에 의해 로딩될 때 로딩되지 않다가 getInstance()가 호출될 때 JVM 메모리에 로드되고 객체를 생성하게 된다.
또한 클래스가 로드될 때 객체가 생성되기 때문에 multi-thread 환경에서도 안전하게 사용이 가능하다.
public class Singletone {
private int num = 0;
private static class SingletonHelper {
private static final Singletone SINGLETON = new Singletone();
}
public static Singletone getSingletone() {
return SingletonHelper.SINGLETON;
}
// num 증가
public void plusNum() {
num++;
}
// get num
public int getNum() {
return num;
}
}
싱글톤은 하나만 할당하고 거기에서 지지고 볶고 하는 공통 객체 생성 방법이다.