Шаблон Java Singleton: объяснение методов инициализации Eager и Lazy

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

  1. Жаркая инициализация:
    При этом подходе экземпляр одноэлементного класса создается быстро, то есть во время загрузки класса. Экземпляр создается независимо от того, нужен он или нет.

    Вот пример реализации шаблона Singleton с использованием быстрой инициализации в Java:

    public class Singleton {
       private static final Singleton instance = new Singleton();
       // Private constructor to prevent instantiation from other classes
       private Singleton() {
       }
       public static Singleton getInstance() {
           return instance;
       }
    }

    В этом примере переменная instanceинициализируется сразу же при загрузке класса, а метод getInstance()возвращает предварительно инициализированный экземпляр.

  2. Ленивая инициализация.
    При этом подходе экземпляр одноэлементного класса создается лениво, т. е. при первом запросе. Это позволяет более эффективно использовать память, поскольку экземпляр создается только при необходимости.

    Вот пример реализации шаблона Singleton с использованием ленивой инициализации в Java:

    public class Singleton {
       private static Singleton instance;
       // Private constructor to prevent instantiation from other classes
       private Singleton() {
       }
       public static synchronized Singleton getInstance() {
           if (instance == null) {
               instance = new Singleton();
           }
           return instance;
       }
    }

    В этом примере переменная instanceинициализируется лениво внутри метода getInstance(). Метод сначала проверяет, является ли экземпляр нулевым, и создает его, только если он не существует.

Оба подхода имеют свои преимущества и недостатки. Инициализация Eager по умолчанию обеспечивает потокобезопасность, но может создать экземпляр, даже если это не требуется. С другой стороны, ленивая инициализация создает экземпляр по требованию, но требует дополнительной синхронизации для обеспечения потокобезопасности.