Является ли синглтон в Java потокобезопасным
Что проверяют
Умеете ли вы разделить два разных вопроса: потокобезопасно ли создание единственного экземпляра и потокобезопасен ли сам объект. Заодно проверяют знание модели памяти, на синглтоне удобно спросить про volatile и про безопасную публикацию.
Как отвечать
Сам по себе паттерн не даёт никаких гарантий. Наивная ленивая версия с проверкой на null без синхронизации ломается двумя способами: два потока создают два экземпляра и, что хуже, один поток видит уже не null, но ещё не достроенный объект.
Дальше по вариантам.
Статическое поле, инициализированное при загрузке класса, безопасно: инициализацию класса JVM выполняет под своей блокировкой, повторного входа не будет.
Идиома со вложенным классом-держателем даёт то же самое, но лениво: вложенный класс грузится при первом обращении, синхронизация не нужна вовсе. Это обычный рекомендуемый вариант.
synchronized на методе корректен, но плата берётся с каждого вызова, а нужна она только при первом.
Двойная проверка работает лишь с volatile у поля. Без него модель памяти разрешает переупорядочить запись ссылки и инициализацию полей объекта, и второй поток получит ссылку на полуготовый экземпляр.
enum с единственной константой безопасен по построению и вдобавок устойчив к сериализации и к созданию через рефлексию.
И главное: даже корректно созданный синглтон это разделяемое изменяемое состояние. Поля внутри требуют синхронизации или потокобезопасных коллекций сами по себе.
Где спотыкаются
Показывают двойную проверку без volatile и говорят, что так быстрее. Код выглядит рабочим и годами не падает, а ломается потом, на другой архитектуре процессора или после смены JVM.
Считают, что потокобезопасное создание делает потокобезопасным весь класс. Обычный HashMap внутри синглтона портится при конкурентной записи независимо от того, как создавался экземпляр.
Путают синглтон как паттерн и бин со скоупом singleton в контейнере. Контейнер гарантирует один экземпляр на себя, а не на процесс, и заботу о том, чтобы бин был без состояния, с разработчика никто не снимает.