싱글톤 패턴은 애플리케이션 전체에서 단 하나의 인스턴스만 존재하도록 보장하는 디자인 패턴입니다. 싱글톤 클래스 자체가 인스턴스를 만들고 관리하며, 전역 액세스 지점을 제공합니다. 자바에서 싱글톤 패턴을 구현하는 방법은 다음과 같습니다.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
이 코드에서 Singleton
클래스는 다음과 같은 특징을 가집니다.
instance
변수는 클래스의 단일 인스턴스를 저장하는 정적(static) 변수입니다.getInstance()
메소드는 인스턴스를 반환하며, 인스턴스가 없으면 새로 생성합니다.멀티스레드 환경에서 동시성 문제가 발생할 수 있습니다. 위 코드에서 여러 스레드가 동시에 getInstance()
메소드를 호출하면, 두 개 이상의 인스턴스가 생성될 수 있습니다. 이를 해결하기 위해서는 동기화가 필요합니다.
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
클래스 로딩 시점에 인스턴스를 생성하므로 동기화 문제가 발생하지 않습니다. 하지만 싱글톤 객체가 필요하지 않더라도 항상 인스턴스를 생성하므로 리소스 낭비가 있을 수 있습니다.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
getInstance()
메소드에 synchronized
키워드를 추가하여 동기화를 보장합니다. 하지만 이 방식은 성능 저하가 발생할 수 있습니다.
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
이 방식은 동기화 블록을 최소화하여 성능을 개선합니다. 첫 번째 if
문에서 인스턴스가 없는 경우에만 동기화 블록을 실행합니다. volatile
키워드는 인스턴스 변수의 최신 상태를 보장합니다.
public class Singleton {
private static class SingletonHelper {
private static final Singleton instance = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonHelper.instance;
}
}
이 방식은 클래스 로딩 시점에 인스턴스를 생성하지만, 실제로 getInstance()
가 호출될 때까지 인스턴스를 생성하지 않습니다. 동기화 문제도 없고, 리소스 낭비도 없습니다.
public enum Singleton {
INSTANCE;
public void doSomething() {
// ...
}
}
Java 5 이후 버전에서는 enum을 사용하여 싱글톤 패턴을 구현할 수 있습니다. 이 방식은 Thread-safe하고 직렬화가 가능하며, 리플렉션에 대한 보안성이 높습니다.
요약하면, 싱글톤 패턴은 애플리케이션 전체에서 단 하나의 인스턴스만 존재하도록 보장합니다. 장점과 단점이 있으며, 동시성 문제를 해결하기 위해 여러 가지 방법이 있습니다. 상황에 따라 적절한 방법을 선택하여 사용해야 합니다.