
Java에서 싱글톤이란 무엇입니까?
싱글톤은 가장 단순한 클래스 수준 디자인 패턴 중 하나입니다. 때때로 사람들은 "이 클래스는 싱글톤입니다"라고 말하는데, 이는 클래스가 싱글톤 디자인 패턴을 구현한다는 것을 의미합니다. 인스턴스화를 단일 객체로 제한하는 클래스를 작성해야 하는 경우가 있습니다. 예를 들어 로깅 또는 연결을 담당하는 클래스 싱글톤 디자인 패턴은 이를 달성하는 방법을 설명합니다. 싱글톤은 다음 두 가지 작업을 수행하는 디자인 패턴입니다.-
클래스의 인스턴스가 하나만 있음을 보장합니다.
-
해당 인스턴스에 대한 글로벌 액세스의 단일 지점을 제공합니다.
-
개인 생성자. 이는 클래스 자체 외부에서 클래스의 객체를 생성하는 기능을 제한합니다.
-
클래스의 인스턴스를 반환하는 공용 정적 메서드입니다. 이 메서드를 getInstance 라고 합니다 . 이것은 클래스 인스턴스에 대한 전역 액세스 지점입니다.
구현 옵션
싱글톤 디자인 패턴은 다양한 방식으로 적용됩니다. 각 옵션은 나름대로 좋고 나쁩니다. 항상 그렇듯이 완벽한 옵션은 없지만 하나를 위해 노력해야 합니다. 우선, 좋은 것과 나쁜 것을 구성하는 것과 디자인 패턴의 다양한 구현을 평가하는 방법에 영향을 미치는 메트릭을 결정합시다. 좋은 것부터 시작합시다. 다음은 구현을 보다 풍부하고 매력적으로 만드는 요소입니다.-
지연 초기화: 필요할 때까지 인스턴스가 생성되지 않습니다.
-
간단하고 투명한 코드: 물론 이 메트릭은 주관적이지만 중요합니다.
-
스레드 안전성: 다중 스레드 환경에서 올바른 작동.
-
다중 스레드 환경의 고성능: 리소스를 공유할 때 스레드 차단이 거의 또는 전혀 없습니다.
-
지연 초기화 없음: 필요 여부와 관계없이 응용 프로그램 시작 시 클래스가 로드될 때(역설적으로 IT 세계에서는 게으른 것이 좋습니다)
-
복잡하고 읽기 어려운 코드. 이 지표도 주관적입니다. 눈에서 피가 나기 시작하면 구현이 최선이 아니라고 가정합니다.
-
스레드 안전성이 부족합니다. 즉, "스레드 위험"입니다. 다중 스레드 환경에서 잘못된 작업입니다.
-
다중 스레드 환경에서 성능 저하: 스레드는 리소스를 공유할 때 항상 또는 자주 서로를 차단합니다.
암호
이제 다양한 구현 옵션을 고려하고 장단점을 표시할 준비가 되었습니다.단순한
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
가장 간단한 구현. 장점:
-
간단하고 투명한 코드
-
스레드 안전성
-
다중 스레드 환경에서 고성능
- 게으른 초기화가 없습니다.
지연 초기화
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
장점:
-
게으른 초기화.
-
스레드로부터 안전하지 않음
동기화된 액세스
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
장점:
-
게으른 초기화.
-
스레드 안전성
-
멀티스레드 성능 저하
이중 확인 잠금
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
장점:
-
게으른 초기화.
-
스레드 안전성
-
다중 스레드 환경에서 고성능
-
Java 1.5 이하 이전 버전에서는 지원하지 않음(1.5 버전부터 volatile 키워드 사용이 수정됨)
클래스 홀더
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
장점:
-
게으른 초기화.
-
스레드 안전.
-
다중 스레드 환경에서 고성능.
-
올바른 작업을 위해서는 싱글톤 개체가 오류 없이 초기화된다는 보장이 필요합니다. 그렇지 않으면 getInstance 메서드 에 대한 첫 번째 호출 에서 ExceptionInInitializerError 가 발생 하고 모든 후속 호출에서 NoClassDefFoundError 가 발생합니다 .
구현 | 지연 초기화 | 스레드 안전성 | 멀티스레드 성능 | 언제 사용합니까? |
---|---|---|---|---|
단순한 | - | + | 빠른 | 절대. 또는 지연 초기화가 중요하지 않은 경우일 수도 있습니다. 그러나 결코 나아지지 않을 것입니다. |
지연 초기화 | + | - | 해당 없음 | 멀티스레딩이 필요하지 않을 때 항상 |
동기화된 액세스 | + | + | 느린 | 절대. 또는 멀티스레드 성능이 중요하지 않을 때 가능합니다. 그러나 결코 나아지지 않을 것입니다. |
이중 확인 잠금 | + | + | 빠른 | 드물게 싱글톤을 생성할 때 예외 처리가 필요한 경우(클래스 홀더 싱글톤이 적용되지 않는 경우) |
클래스 홀더 | + | + | 빠른 | 멀티스레딩이 필요할 때마다 싱글톤 객체가 문제 없이 생성된다는 보장이 있습니다. |
싱글톤 패턴의 장단점
일반적으로 싱글톤은 예상대로 정확히 수행합니다.-
클래스의 인스턴스가 하나만 있음을 보장합니다.
-
해당 인스턴스에 대한 글로벌 액세스의 단일 지점을 제공합니다.
-
싱글톤은 단일 책임 원칙을 위반합니다. 직접적인 의무 외에도 싱글톤 클래스는 인스턴스 수를 제어합니다.
-
싱글톤에 대한 일반 클래스의 종속성은 클래스의 공개 계약에서 볼 수 없습니다.
-
전역 변수가 잘못되었습니다. 궁극적으로 싱글톤은 엄청난 전역 변수가 됩니다.
-
싱글톤의 존재는 애플리케이션 전체와 특히 싱글톤을 사용하는 클래스의 테스트 가능성을 감소시킵니다.
GO TO FULL VERSION