Шаблон синглтон не прост

Предисловие

Привет всем, я очень умный. Шаблон проектирования — это набор методов проектирования кода, которые неоднократно использовались, известны большинству людей, классифицированы и каталогизированы. Цель использования шаблонов проектирования — повторно использовать код, облегчить его понимание другими и обеспечить надежность кода.

Сегодня я поделюсь некоторыми важными знаниями о шаблоне Singleton, надеясь, что они будут вам полезны.

Определение шаблона Singleton

Шаблон синглтон — это широко используемый шаблон творческого проектирования, который содержит в своей базовой структуре только специальный класс, называемый синглтоном. Шаблон синглтон может гарантировать, что в системе существует только один экземпляр объекта для класса, использующего шаблон синглтон.

Характеристики одноэлементного шаблона

  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 гарантирует, что перечисление является естественным одноэлементным, потокобезопасным, автоматически поддерживает механизм сериализации, предотвращает повторное создание новых объектов при десериализации и предотвращает множественное создание экземпляров.

Подведем итог

Существует множество способов реализации одноэлементного режима, которые сравниваются по трем аспектам: является ли он потокобезопасным, является ли он ленивой загрузкой и предотвращает ли он создание отражения, а именно:

Реализация шаблона Singleton Это потокобезопасно? Стоит ли откладывать загрузку Следует ли предотвращать рефлексивные сборки
Голодный китайский стиль да нет нет
стиль ленивого человека нет да нет
Двойной замок обнаружения да да нет
статический внутренний класс да да нет
перечислять да нет да

Паттерн синглтон часто встречается на собеседованиях и в работе.Какие паттерны проектирования вы часто используете в своей работе? Не стесняйтесь оставлять сообщение ниже.

-----КОНЕЦ-----

​ Друзья, кому понравилась эта статья, то эта статья должна понравиться и вам! Тогда поставь лайк!

рекомендация

отblog.csdn.net/qq_41917138/article/details/126112168