단일 모드 소기

4859 단어 Singleton

콘셉트


단일 예제에 대한 위키백과 설명 참조:
단례 모델은 단자 모델이라고도 부르며 자주 사용하는 소프트웨어 디자인 모델이다.이 모델을 응용할 때, 단일 대상의 클래스는 반드시 하나의 실례만 존재할 것을 보장해야 한다.
위키백과의 실현 방향을 계속 인용하다.
단일 모드를 실현하는 사고방식은 하나의 클래스가 대상의 인용(영원히 동일)과 이 실례를 얻을 수 있는 방법(정적 방법이어야 하며 getInstance라는 이름을 사용합니다)이다.우리가 이 방법을 호출할 때, 클래스가 가지고 있는 인용이 비어 있지 않으면 이 인용을 되돌려주고, 클래스가 유지하고 있는 인용이 비어 있으면 클래스의 실례를 만들고, 실례의 인용을 클래스가 유지하고 있는 인용에 부여한다.또한 우리는 이 클래스의 구조 함수를 사유 방법으로 정의하여 다른 곳의 코드는 이 클래스의 구조 함수를 호출하여 이 클래스의 대상을 실례화할 수 없고, 이 클래스가 제공하는 정적 방법을 통해서만 이 클래스의 유일한 실례를 얻을 수 있다.
단례적인 사고방식은 이렇게 간단하다. 다른 디자인 모델처럼 일반적으로 몇 가지 종류가 있지 않다.그것은 단지 하나의 종류만 있다.

Java의 단일 예제 구현


게으름뱅이와 아사자식


자바의 단례 모델을 토론할 때 원숭이들은 일반적으로 두 가지 실현 방식인 게으름뱅이와 굶주림식을 언급한다.왜 이 두 가지 명칭이 있습니까?실현 코드를 보고 나면 갑자기 깨닫게 될 거라고 믿습니다.
아사자식, 나는 아사자입니다. 기다릴 수 없습니다. 종류를 만들 때 나에게 먹을 것(실례화 대상)을 주어야 합니다. 그렇지 않으면 나는 굶어 죽을 것입니다.
public class Singleton{
    // 。
    private final static Singleton INSTANCE = new Singleton();
    
    // ( ) 
    private Singleton(){}

    // , 。 , 。
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

게으름뱅이식, 나는 게으름뱅이야. 너는 나에게 일을 하라고 해. 게으름은 내 천성이야. 이건 나를 탓할 수 없어.
public class Singleton{
    private static Singleton INSTANCE;

    private Singleton(){}

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

OK, 단일 모드는 이렇게 간단해, 끝났어.허허, 정말 끝난 거야?도안 도삼파!
위의 두 가지 실현은 확실히 한식과 게으름뱅이를 실현했다.그리고 그것들은 단선 아래에서 잘 운행할 수 있다.그런데 만약에 우리가 이걸 다선정에 적용한다면?한번 해 보면 아사자식은 여전히 꿋꿋하고 멋지게 대처한다는 것을 알 수 있다.게으름뱅이가 순식간에 터졌어요!"어쩔 수 없어, 누가 너더러 게으르라고 했어, 나와서 빈둥거리면 언제나 갚아야 해."코드라도 게으름은 대가를 치러야지~~농담이야^ ^,폭발의 원인은 틀림없이 게으름의 원인이 아닐 것이다. 라인이 동기화되는 문제로 인해 비라인이 안전한 게으름뱅이식이 생겼다.
위의 게으름뱅이가 다선정에서 폭발했으니 구해야지. 죽어도 구해주지 않을 수는 없잖아~

다선정 하 게으름뱅이 식 자아 구원


게으름뱅이 폭발의 원인을 알았을 때 라인이 동기화되는 문제를 알 수 있다. 우리의 가장 간단한 구조 방법은 바로 동기화 잠금을 직접 해서 라인이 안전한 게으름뱅이를 만드는 것이다.
public class Singleton{
    private static Singleton INSTANCE;

    private Singleton(){}

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

간단하게 getInstance 방법을 잠그면 비선정 안전한 게으름뱅이를 선정 안전으로 바꿀 수 있습니다. 간단하죠!그러나 세상에 공짜가 없는 것처럼 이렇게 간단한 구제법은 대가를 치러야 한다.따라서 이런 실현 방법은 효율을 떨어뜨릴 수 있다.
좋아, 효율이 낮아, 내가 고쳐도 안 돼.수정을 거친 후에 우리는 또 다른 라인 안전 게으름뱅이식 단례를 얻었다. 이중 검사 자물쇠(Double-Checked Locking)
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;
    }
}

이 방법이 이전의 라인보다 안전하고 게으름뱅이식 효율이 높은 이유는 이전의 실현 방법은 매번 얻는 예마다 동기화를 해야 하기 때문에 매번 한 라인만 getInstance 방법에 들어가서 실례를 얻을 수 있기 때문이다.이 방법은 동기화 블록을 축소하고 인스타그램이null일 때만 동기화 접근을 한다.이후에는 동기화할 필요가 없고, 동시에 실례를 얻을 수 있다.
JDK 1.5 이전에 이런 방법을 이용한 것이 문제가 있다는 것을 많은 사람들이 알고 있다.그러나 JDK 1.5 이후 자바의 메모리가 수정되어 1.5 이후 정상적으로 작동할 수 있어 안심하고 사용할 수 있다.

기타 실현 방법


정적 내부 클래스를 사용하여 실현
public class Singleton{
    private static class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton(){}

    public static final Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

이 방법은 정적 내부류의 특성을 이용하여 게으름뱅이와 유사한 단일 모델을 실현하였다
매거 실현
public enum Singleton{
    INSTANCE;
}

매거적으로 실현된 단례는 더 이상 간단할 수 없을 정도로 간단해졌으니,singleton을 직접 사용할 수 있다.INSTANCE에서 단일 인스턴스를 가져옵니다.그것은 비록 간단하지만, 또한 라인의 안전한 실현 방법이며, 또한 서열화할 수 있는 것이다.Effective Java 2판에서도 이러한 방법을 추천합니다. 단일 요소의 매거 유형은 이미 Singleton을 실현하는 가장 좋은 방법이 되었습니다.

단일 Java에서의 응용

  • Java.awt.Toolkit with getDefaultToolkit()
  • Java.awt.Desktop with getDesktop()
  • java.lang.Runtime

  • java.lang.Runtime에서 사용하는 단일 예(아사자식, 스레드 보안 관련 없음):
    public class Runtime{
        private static Runtime currentRuntime = new Runtime();
    
        public static Runtime getRuntime(){
            return currentRuntime;
        }
        
        private Runtime(){}
    
        //...  
    }

    참고 자료


    위키백과 StackExchange 매거를 사용하여 단례를 실현하다 Effective Java 제3조 제안

    좋은 웹페이지 즐겨찾기