Блокировка с двойной проверкой — это шаблон проектирования программного обеспечения, используемый в параллельном программировании, чтобы гарантировать создание только одного экземпляра объекта, даже если несколько потоков одновременно обращаются к коду. Цель блокировки с двойной проверкой — повысить производительность за счет сведения к минимуму необходимости синхронизации в критических разделах кода.
В контексте создания объекта блокировка с двойной проверкой включает проверку того, был ли уже создан объект, прежде чем получить блокировку для создания нового экземпляра. Он состоит из двух проверок:
-
Первая проверка выполняется без получения блокировки и проверяет, был ли уже создан объект. Эта проверка известна как «однократная проверка» или «быстрый путь» и предназначена для быстрого выхода из критического раздела, когда объект уже существует.
-
Вторая проверка выполняется после получения блокировки и повторно проверяется, был ли создан объект. Эта дополнительная проверка необходима для обработки сценария, когда несколько потоков одновременно проходят первую проверку и один из них получает блокировку для создания объекта, а остальные ждут. Вторая проверка предотвращает ненужное воссоздание объекта последующими потоками.
Вот пример шаблона блокировки с двойной проверкой в Java:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// private constructor to prevent instantiation
}
public static Singleton getInstance() {
if (instance == null) { // Single-check
synchronized (Singleton.class) {
if (instance == null) { // Double-check
instance = new Singleton();
}
}
}
return instance;
}
}
В этом примере метод getInstance()проверяет, имеет ли переменная instanceзначение nullбез получения блокировки (однократная проверка). Если оно равно null, происходит блокировка класса Singleton(двойная проверка). Как только блокировка получена, он снова проверяет переменную instance, чтобы убедиться, что она не была создана другим потоком во время ожидания. Если он по-прежнему равен null, создается новый экземпляр класса Singleton.
Благодаря использованию блокировки с двойной проверкой шаблон сводит к минимуму необходимость синхронизации, повышая производительность в сценариях, когда несколько потоков пытаются одновременно получить доступ к экземпляру.