>  기사  >  Java  >  Java 싱글턴 패턴의 차이점은 무엇입니까?

Java 싱글턴 패턴의 차이점은 무엇입니까?

coldplay.xixi
coldplay.xixi원래의
2020-08-17 14:03:161716검색

Java 싱글톤 모드의 차이점은 다음과 같습니다. 1. Hungry Man의 클래스가 로드되면 싱글톤 초기화가 완료되는 반면, Lazy Man은 getInstance를 호출할 때만 싱글톤을 초기화하기 위해 돌아갑니다. Hungry Man 스타일은 본질적으로 스레드로부터 안전하지만 Lazy Man 스타일 자체는 스레드로부터 안전하지 않습니다.

Java 싱글턴 패턴의 차이점은 무엇입니까?

[관련 학습 추천 : java 기본 튜토리얼]

Java 싱글턴 모드의 차이점은 다음과 같습니다.

1. Lazy 싱글턴

//懒汉式单例类.在第一次调用的时候实例化自己   
public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
}

싱글 톤으로 건설 방법을 제한하여 클래스가 외부적으로 인스턴스화되는 것을 방지하려면 동일한 가상 머신 범위 내에서 Singleton의 유일한 인스턴스는 getInstance() 메서드를 통해서만 액세스할 수 있습니다.

(실제로 Java 리플렉션 메커니즘을 통해 개인 생성자를 사용하여 클래스를 인스턴스화하는 것이 가능합니다. 이는 기본적으로 모든 Java 싱글톤 구현을 무효화합니다. 이 문제는 여기서 논의하지 않습니다. 리플렉션 메커니즘을 무시합시다. 존재하지 않습니다. .)

그러나 위의 게으른 스타일 싱글톤 구현은 스레드 안전 문제를 고려하지 않습니다. 스레드 안전을 달성하려면 여러 싱글톤 인스턴스가 나타날 가능성이 높습니다. 게으른 스타일 싱글턴의 스레드 안전성을 보장하기 위해 getInstance 메소드를 변환합니다. 처음으로 싱글턴 모드에 노출되고 스레드 안전성에 대해 잘 모르는 경우 다음 세 가지 작은 항목을 건너뛰고 예를 들어 읽기가 끝날 때까지 기다렸다가 다시 스레드 안전 문제를 고려하세요.

1. getInstance 메소드에 동기화를 추가하세요

2.

public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
}

3. 정적 내부 클래스

public static Singleton getInstance() {  
        if (singleton == null) {    
            synchronized (Singleton.class) {    
               if (singleton == null) {    
                  singleton = new Singleton();   
               }    
            }    
        }    
        return singleton;   
    }
이런 종류는 위의 1과 2보다 낫습니다. 스레드 안전성을 달성할 뿐만 아니라 동기화로 인한 성능 영향도 방지합니다.

2. Hungry-style 싱글톤

public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
}
Hungry-Han 스타일은 클래스가 생성될 때 시스템 사용을 위한 정적 객체를 이미 생성했으며 나중에 변경하지 않으므로 본질적으로 스레드로부터 안전합니다.

3. 등록된 싱글톤(무시 가능)

//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
}
등록된 싱글톤은 실제로 싱글톤 클래스의 인스턴스 세트를 유지하고 이러한 인스턴스를 Map(등록 북)에 저장합니다. 등록되지 않은 항목은 먼저 등록된 후 반환됩니다.

여기서는 등록 스타일 싱글턴을 무시할 수 있다고 표시했습니다. 우선 정적 메서드 블록과 해당 싱글턴 때문에 내부 구현에서는 여전히 중국 스타일 싱글턴을 사용합니다. 클래스가 로드될 때 인스턴스화됩니다.

4. Hungry Man 스타일과 Lazy Man 스타일의 차이점

Hungry Man과 Lazy Man이라는 이름에서

Hungry Man은 클래스가 로드되면 싱글톤이 초기화된다는 의미입니다. getInstance, 싱글톤 이미 존재합니다.

게으른 사람은 게으르고 getInstance가 호출될 때만 이 싱글톤을 초기화하기 위해 돌아갑니다.

또한 다음 두 가지 방법은 다음 두 가지 점에서 구별됩니다.

1. 스레드 안전성:

Hungry Chinese 스타일은 본질적으로 스레드에 안전하며 문제 없이 멀티스레딩에 직접 사용할 수 있습니다.

게으른 사람 공식 자체는 스레드로부터 안전하지 않습니다. 스레드 안전성을 달성하기 위해 위의 1, 2, 3과 같이 작성하는 방법이 여러 가지가 있습니다. 이 세 가지 구현은 리소스 로딩 및 성능에 약간의 차이가 있습니다.

2. 리소스 로딩 및 성능:

Hungry Chinese 스타일은 클래스가 생성될 때 정적 개체를 인스턴스화합니다. 이 싱글톤이 나중에 사용되는지 여부에 관계없이 일정량의 메모리를 차지하지만 그에 따라 처음에는 리소스가 초기화되었기 때문에 첫 번째 호출 속도도 더 빨라집니다.

이름에서 알 수 있듯이 게으른 스타일은 첫 번째 호출이 사용될 때까지 개체가 인스턴스화되지 않습니다. 필요합니다. 초기화하는 동안 해야 할 일이 많으면 성능이 약간 지연되고 그러면 배고픈 사람과 같습니다.

세 가지 구현 1, 2, 3에는 몇 가지 차이점이 있습니다.

첫 번째는 스레드로부터 안전하지만 매번 동기화가 필요하므로 결국 성능에 영향을 미칩니다. , 99% 이 경우 동기화가 필요하지 않습니다.

두 번째 유형에서는 싱글톤이 처음 호출될 때만 동기화가 수행되도록 getInstance에서 두 번의 null 검사가 수행됩니다. -안전하고 동시 동기화의 성능 손실이 필요하지 않음

세 번째 방법은 클래스 로더 메커니즘을 사용하여 인스턴스를 초기화할 때 스레드가 하나만 있도록 보장하므로 스레드로부터 안전하고 성능 손실이 없으므로 일반적으로 나는 경향이 있습니다. 이것을 사용하려면.

관련 학습 권장 사항:

프로그래밍 비디오

위 내용은 Java 싱글턴 패턴의 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.