싱글톤 패턴에는 다음과 같은 특징이 있습니다.
1. 싱글톤 클래스는 인스턴스를 하나만 가질 수 있습니다.
2. 싱글톤 클래스는 고유한 인스턴스를 생성해야 합니다.
3. 싱글톤 클래스는 이 인스턴스를 다른 모든 객체에 제공해야 합니다.
싱글톤 패턴은 클래스의 인스턴스가 하나만 존재하도록 보장하고, 자체적으로 인스턴스화하여 이 인스턴스를 전체 시스템에 제공합니다. 컴퓨터 시스템에서 스레드 풀, 캐시, 로그 개체, 대화 상자, 프린터 및 그래픽 카드 드라이버 개체는 종종 싱글톤으로 설계됩니다. 이러한 응용 프로그램은 모두 리소스 관리자의 기능을 어느 정도 갖추고 있습니다. 각 컴퓨터에는 여러 대의 프린터가 있을 수 있지만 두 개의 인쇄 작업이 동시에 프린터로 출력되는 것을 방지하기 위해 프린터 스풀러는 하나만 있을 수 있습니다. 각 컴퓨터에는 여러 개의 통신 포트가 있을 수 있으며, 하나의 통신 포트가 동시에 두 개의 요청에 의해 호출되는 것을 방지하기 위해 시스템은 이러한 통신 포트를 중앙에서 관리해야 합니다. 간단히 말해서, 싱글톤 모드를 선택하는 목적은 일관성 없는 상태를 피하고 장기적인 정책을 피하는 것입니다.
먼저, 고전적인 싱글톤 구현을 살펴보겠습니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 싱글턴 {
개인 정적 싱글턴 고유 인스턴스 = null;
개인 싱글턴() {
// 인스턴스화를 무효화하기 위해서만 존재합니다.
}
공개 정적 싱글턴 getInstance() { if (uniqueInstance == null) {
UniqueInstance = 새로운 싱글턴();
}
고유 인스턴스를 반환합니다.
}
// 다른 방법들...
}
Singleton은 생성 방법을 private으로 제한하여 클래스가 외부에서 인스턴스화되는 것을 방지합니다. 동일한 가상 머신 범위 내에서 Singleton의 유일한 인스턴스는 getInstance() 메서드를 통해서만 액세스할 수 있습니다. (실제로 Java 리플렉션 메커니즘을 통해 전용 생성자를 사용하여 클래스를 인스턴스화하는 것이 가능하며, 이는 기본적으로 모든 Java 싱글톤 구현을 무효화합니다. 이 문제는 여기서 논의하지 않습니다. 리플렉션 메커니즘이 존재하지 않는다고 가정하겠습니다.)
그러나 위의 구현에서는 스레드 안전성 문제를 고려하지 않습니다. 소위 스레드 안전이란 코드가 있는 프로세스에서 동시에 실행 중인 여러 스레드가 있는 경우 이러한 스레드가 이 코드를 동시에 실행할 수 있음을 의미합니다. 각 실행의 결과가 단일 스레드 실행의 결과와 동일하고 다른 변수의 값도 예상과 동일하면 스레드로부터 안전합니다. 즉, 클래스나 프로그램에서 제공하는 인터페이스는 스레드에 대한 원자적 작업이거나 여러 스레드 간의 전환으로 인해 인터페이스의 실행 결과에 모호성이 발생하지 않으므로 동기화 문제를 고려할 필요가 없습니다. 분명히 위의 구현은 스레드 안전성 요구 사항을 충족하지 않으며 여러 Singleton 인스턴스가 동시 환경에 나타날 가능성이 높습니다.
다음과 같이 코드 코드를 복사합니다.
//Hungry 스타일의 싱글톤 클래스입니다. 클래스가 초기화될 때 자체적으로 인스턴스화됩니다.
공개 클래스 Singleton1 {
//개인 기본 생성자
비공개 싱글턴1() {}
//이미 자체적으로 인스턴스화됨
private static final Singleton1 싱글 = new Singleton1();
//정적 팩토리 메소드
공개 정적 싱글턴1 getInstance() {
싱글 반환;
}
}
//게으른 싱글톤 클래스. 처음 호출될 때 인스턴스화됩니다.
공개 클래스 Singleton2 {
//개인 기본 생성자
비공개 싱글턴2() {}
//주의하세요. 여기에는 최종 결과가 없습니다.
개인 정적 Singleton2 단일=null;
//정적 팩토리 메소드
공개 동기화 정적 Singleton2 getInstance() {
if (단일 == null) {
싱글 = 새로운 싱글턴2();
}
싱글 반환;
}
}