По какой логике работает метод getInstance?

Метод getInstance является популярным шаблоном проектирования Singleton (одиночка) в языке программирования Java. В основе этого шаблона лежит идея создавать только один экземпляр класса и предоставлять глобальную точку доступа к этому экземпляру.

Для понимания логики работы метода getInstance важно разобраться в его реализации. Класс, который управляет созданием экземпляра и предоставляет доступ к нему, должен иметь статическое поле, чтобы хранить ссылку на этот экземпляр, а также приватный конструктор, чтобы запретить прямое создание экземпляров класса извне.

public class Singleton {
    private static Singleton instance;
    
    // Приватный конструктор
    private Singleton() {
        // Инициализация экземпляра класса
    }
    
    // Метод для получения единственного экземпляра класса
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

При первом вызове метода getInstance, он проверяет, существует ли уже экземпляр класса Singleton. Если нет, то происходит блокировка синхронизации с помощью synchronized (Singleton.class), чтобы предотвратить создание двух экземпляров одновременно. Затем внутри блока проверяется еще раз, есть ли уже экземпляр класса, потому что другой поток, который был заблокирован ранее, мог успеть создать экземпляр. Если instance все еще равен null, то создается новый экземпляр класса с помощью конструктора new Singleton().

При последующих вызовах метода getInstance, уже существующий экземпляр класса Singleton возвращается без создания нового экземпляра.

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

Однако, следует заметить, что в многопоточной среде может появиться проблема, связанная с побочными эффектами синхронизации и видимостью изменений переменных между потоками, что может привести к созданию нескольких экземпляров класса Singleton. Для решения этой проблемы используется метод "double-checked locking", который был использован в примере выше. Он гарантирует атомарность создания экземпляра класса и избегание повторных созданий при многопоточной обработке.