클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다.
public class Singleton {
private static Singleton uniqueinstance; // 하나뿐인 인스턴스를 저장하는 정적 변수
private Singleton() {} // 생성자를 private로 선언
public static Singleton getInstance() {
// 클래스 인스턴스를 하나만 생성
if(uniqueInstance == null) { // 인스턴스가 생성되지 않았을 때
uniqueInstance = new Singleton(); // 객체 생성
}
return uniqueInstance;
}
}
문제점: 멀티스레딩 문제 발생한다. 동시에 실행되었을 때,인스턴스가 생성되었는지 모르고 2개의 인스턴스를 생성하게 된다
public class Singleton {
private static Singleton uniqueinstance; // 하나뿐인 인스턴스를 저장하는 전역변수
private Singleton() {} // 생성자를 private로 선언
public static synchronized Singleton getInstance() {
// 클래스 인스턴스를 하나만 생성
if(uniqueInstance == null) { // 인스턴스가 생성되지 않았을 때
uniqueInstance = new Singleton(); // 객체 생성
}
return uniqueInstance;
}
}
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
}
class Singleton {
private static Singleton instance;
private Singleton() {}
// static 블록을 이용해 예외 처리
static {
try {
instance = new Singleton();
} catch (Exception e) {
throw new RuntimeException("객체 생성 오류");
}
}
public static Singleton getInstance() {
return instance;
}
}
public class Singleton {
private volatile static Singleton uniqueinstance;
private Singleton() {}
public static Singleton getInstance() {
// 클래스 인스턴스를 하나만 생성
if(uniqueInstance == null) { // 인스턴스가 있는지 확인
synchronized (Singleton.class) { // 동기화
if(uniqueInstance == null) { // 인스턴스가 있는지 재확인
uniqueInstance = new Singleton(); // 객체 생성
}
}
}
return uniqueInstance;
}
}
public enum Singleton {
UNIQUE_INSTANCE;
}
public class SingletonClient {
public static void main(String[] args) {
Singleton singleton = Singleton.UNIQUE_INSTANCE;
}
}
** 리플렉션: 런타임에 결정될 클래스 타입을 컴파일 시에 결정한 것처럼 행동할 수 있게 하는 API
class Singleton {
private Singleton() {}
// static 내부 클래스를 이용
// Holder로 만들어, 클래스가 메모리에 로드되지 않고 getInstance 메서드가 호출되어야 로드됨
private static class SingleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingleInstanceHolder.INSTANCE;
}
}