2017-11-27 1 views
4

열거 형 싱글 톤에 대해 궁금 해서요. 성능입니다.싱글 톤 열거 형 성능

우리가 멀티 스레드 환경을 가지면 인스턴스가 생성 될 때 순간을 동기화해야합니다. 그것은 게으른 구현의

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

이 나를 위해 좋은 :

간단하게, 우리는 그와 같은 예를 Somethink를 작성의 getInstance 호출 된 함수()에 대한 모드를 동기화 할 수 있습니다. 그러나 동기화 된 방법은 느립니다. 더블 로킹을 사용하면 더 빠르게 할 수 있습니다.

enum은 어떻습니까? 싱글 톤을 enum으로 구현하면 singleton 인스턴스가 처음 사용할 때 만들어집니다. 다음으로 현재 인스턴스를 사용합니다.

어떻게 작동합니까? 기존 인스턴스를 가져 오려면 느린 암시 적 동기화 메서드가 있습니까? 아니면 이중 잠금이 구현되어 있습니까?

답변

1

enum과 함께 지연 초기화가 없습니다. 클래스가로드 될 때 단순히 인스턴스를 작성합니다.

싱글 톤을 enum으로 구현하면 싱글 톤 인스턴스가 처음 사용할 때 만들어집니다.

"처음 사용"하면 실제로 "클래스가로드 될 때"를 의미하는 경우에만 해당됩니다.

private static final Singleton instance = new Singleton(); 

public static Singleton getInstance() { 
    return instance; 
} 
+0

클래스가 * 초기화 될 때'enum' 상수가 생성됩니다. 'instance' 필드와 정확히 같습니다. 초기화 시간 [정확히 지정] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1). "처음 사용할 때"로 요약 할 수 있습니다 ... – Holger

3

열거는 스레드 안전하고도 싱글 톤을 구현하는 the recommended way입니다 : 귀하의 예제를 사용하여 즉

는, 열거는 동등하다.

즉, 열거 형은 지연로드되지 않았습니다. 당신이 게으른로드 싱글을 원하는 경우에, 당신은 (스레드 안전뿐만 아니라 임) Holder pattern를 사용할 수 있습니다

class LazySingleton { 

    private LazySingleton() {} 

    private static class SingletonHelper{ 
     private static final LazySingleton INSTANCE = new LazySingleton(); 
    } 

    public static LazySingleton getInstance(){ 
     return SingletonHelper.INSTANCE; 
    } 
} 
+0

이 'SingletonHelper'는 포함 된 클래스가 싱글 톤 및 그 연산보다 많은 특징을 지니고있는 경우에만 필요합니다. 그렇지 않으면,'LazySingleton'의 게으른 클래스 로딩은'LazySingleton'이'enum'인지 여부와 관계없이'SingletonHelper'의 느린 클래스 로딩과 똑같이 작동합니다. – Holger

1
enum 상수의 초기화는 클래스 초기화에서 일어나는

이 비슷한 당신이 쓴하는

static final Singleton instance = new Singleton(); 

또는

static final Singleton instance; 
static { 
    instance = new Singleton(); 
} 

안전이 사실에서 유래 the JVM perform class initialization under a JVM specific lock 그 :

,

Java 프로그래밍 언어가 다중 스레드이기 때문에 클래스 나 인터페이스를 초기화 할 때주의가 필요합니다. 다른 스레드가 같은 클래스 나 인터페이스를 동시에 초기화하려고 할 수 있기 때문입니다. ... Java Virtual Machine의 구현은 다음 절차를 사용하여 동기화 및 재귀 초기화를 담당합니다.

... 각 클래스 또는 인터페이스 C를 들어

는 고유의 초기화 잠금 LC있다. C에서 LC으로의 매핑은 Java Virtual Machine 구현의 재량에 달려 있습니다. 나는 자바 프로그래머와 같은 사양에서 기술적 인 세부 사항을 많이 남겨

는 ..., 가장 중요한 점은 모든 부합하는 JVM에 의해 구현 된 안전 메커니즘이 있다는 것입니다. 이 클래스의 초기화가 있는지 판단 할 수있을 때 구현 1 단계에서 로크 획득 eliding이 절차를 최적화 (단계 4/5에서 방출) 할 수있다

: 섹션의 단부는 주석을 가지고 메모리 모델의 관점에서, 잠금이 획득되면 존재할 수있는 정렬 이전에 최적화가 수행 될 때까지 모든 것이 발생한다면, 이미 완료된 것입니다.

이것은 물론, 싱글 톤 패턴이 구현의 중요한 포인트는 static final 필드 나중에 액세스는 잠금을 획득하지 않아도된다. 모든 클래스는 초기화되지 않은 상태에서 초기화 된 상태로 정확히 한 번 이동하므로 모든 작업 (모든 단일 패턴 구현을 포함하여)에 영향을 미치므로 모든 JVM이 이러한 기본적인 최적화를 수행 할 것으로 기대할 수 있습니다. 특정 JVM이 이것을하지 않는다고해도 static final 필드는 해당 가상 머신에서 가장 빠른 게으른 싱글 톤 구현이됩니다 ...

관련 문제