싱글턴 패턴은 단순하지 않다

머리말

안녕하세요 여러분, 저는 매우 똑똑합니다. 디자인 패턴은 반복적으로 사용되어 대부분의 사람들에게 알려져 있으며 분류되고 목록화되어 있는 일련의 코드 디자인 경험입니다. 디자인 패턴을 사용하는 목적은 코드를 재사용하고, 다른 사람이 코드를 더 쉽게 이해할 수 있도록 하며, 코드 신뢰성을 보장하는 것입니다.

오늘은 싱글톤 패턴에 대한 몇 가지 관련 지식 포인트를 공유하겠습니다. 이것이 여러분에게 도움이 되기를 바랍니다.

싱글톤 패턴의 정의

싱글톤 패턴은 코어 구조에 싱글톤이라는 특수 클래스만 포함하는 일반적으로 사용되는 생성 디자인 패턴입니다. 싱글톤 패턴은 시스템에서 싱글톤 패턴을 사용하는 클래스에 대해 하나의 객체 인스턴스만 있도록 보장할 수 있습니다.

싱글톤 패턴의 특징

  1. 싱글톤 클래스는 하나의 인스턴스만 가질 수 있습니다.
  2. 싱글톤 클래스는 고유한 인스턴스를 만들어야 합니다.
  3. 싱글톤 클래스는 이 인스턴스를 다른 모든 객체에 제공해야 합니다.

배고픈 중국 스타일

Hungry Style의 특징은 사용 여부에 관계없이 초기화 과정에서 객체 인스턴스가 이미 생성된다는 점이며, 구체적인 코드는 다음과 같습니다.

public class HungrySingleton {
    
    
    // 持有自己类的引用
    private static final HungrySingleton singleton = new HungrySingleton();

    // 私有化构造器
    private HungrySingleton(){}

    // 提供获取实例的静态方法
    public static HungrySingleton getInstance(){
        return singleton;
    }
}

장점: 스레드 안전 문제가 없음

단점: 초기화 단계에서 객체를 생성하는데, 객체를 인스턴스화하는 데 시간이 많이 걸리고, 이 인스턴스가 결국 사용되지 않는다는 점을 가정하면 자원 낭비가 되지 않을까요?

게으른 남자 스타일

게으른 스타일의 특징은 사용할 때만 객체를 인스턴스화한다는 점인데, 상대적으로 게으르다 .사용할 때 인스턴스가 있는지 확인하고, 인스턴스가 있으면 직접 반환한다. 그렇지 않은 경우에는 생성 후 반환되며, 구체적인 코드는 다음과 같습니다.

public class LazySingleton {
    
    
    private static LazySingleton singleton;

    // 私有化构造器
    private LazySingleton(){}

    // 提供获取实例的静态方法
    public static LazySingleton getInstance(){
        // 若对象没有被实例化,则new一下再返回
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

장점: 객체는 사용될 때만 인스턴스화됩니다.

단점: 이 구현의 가장 큰 문제점은 스레드로부터 안전하지 않다는 것입니다. 잠금이 없기 때문에 동시 상황에서 여러 객체가 인스턴스화될 수 있습니다.

이중 감지 잠금 장치

이름에서 알 수 있듯이 이중 감지 잠금은 이중 판단 잠금 메커니즘을 사용하므로 다중 스레드 상황에서 안전하고 고성능을 유지할 수 있습니다 . 게으른 스타일의 업그레이드 버전과 동일합니다. 구체적인 코드는 다음과 같습니다 .

public class DoubleCheckLockingSingleton {
    
    

    // 注意这里多了一个volatile关键字,面试的时候经常会问这个关键字的作用
    private volatile static DoubleCheckLockingSingleton singleton;

    // 私有化构造器
    private DoubleCheckLockingSingleton(){}

    // 提供获取实例的静态方法
    public static DoubleCheckLockingSingleton getInstance(){
        if (singleton == null) {
            synchronized (DoubleCheckLockingSingleton.class) {
                if (singleton == null) {
                    singleton = new DoubleCheckLockingSingleton();
                }
            }
        }
        return singleton;
    }
}

장점: 동시성이 높은 상황에서 사용하기에 적합하며 스레드 안전성을 보장합니다.

단점: 싱글톤은 리플렉션을 통해 파괴될 수 있습니다.

정적 내부 클래스

이름에서 알 수 있듯이 정적 내부 클래스는 정적 내부 클래스를 통해 싱글톤 모드를 구현하며 이 방법을 사용하면 이중 감지 잠금과 동일한 효과를 얻을 수 있습니다. 구체적인 코드는 다음과 같습니다.

public class StaticInnerClassSingleton {
    
    
    // 静态内部类
    private static class SingletonHolder {
        private static final StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
    }

    // 私有化构造器
    private StaticInnerClassSingleton(){}

    // 提供获取实例的静态方法
    public static StaticInnerClassSingleton getInstance() {
        return SingletonHolder.singleton;
    }
}

장점: 스레드 안전성, 정적 내부 클래스의 특성을 사용하여 로딩 지연, 고효율 달성

단점: 싱글톤은 리플렉션을 통해 파괴될 수 있습니다.

낱낱이 세다

Java에서 열거형은 자연스러운 싱글톤입니다 . 각 인스턴스에는 하나의 객체만 있습니다. 이는 Java의 기본 내부 메커니즘에서 제공하는 보장입니다.

public enum EnumSingleton {
    
    
    INSTANCE;
}

장점: JVM은 열거형이 자연스러운 싱글톤이고 스레드로부터 안전하며 자동으로 직렬화 메커니즘을 지원하고 역직렬화가 새 객체를 다시 생성하는 것을 방지하며 다중 인스턴스화를 방지합니다.

요약하다

싱글톤 모드를 구현하는 방법은 여러 가지가 있는데, 이를 스레드로부터 안전한지, 지연 로딩인지, 리플렉션 생성을 방지하는지 등 세 가지 측면에서 비교하면 다음과 같습니다.

싱글톤 패턴 구현 스레드로부터 안전합니까? 지연 로드 여부 반사 빌드를 방지할지 여부
배고픈 중국 스타일 아니요 아니요
게으른 남자 스타일 아니요 아니요
이중 감지 잠금 장치 아니요
정적 내부 클래스 아니요
낱낱이 세다 아니요

싱글톤 패턴은 인터뷰나 업무에서 자주 접하게 되는데, 작업에서는 어떤 디자인 패턴을 자주 사용하시나요? 아래에 메시지를 남겨주세요.

-----끝-----

​ 이 글을 좋아하는 친구라면, 이 글을 좋아해야 합니다! 그럼 좋아요를 눌러주세요!

추천

출처blog.csdn.net/qq_41917138/article/details/126112168