Ваш код не является "сплошным":
- конструктор должен быть приватным для одиночного
- вы не должны синхронизировать метод
getInstance()
, хотя вам нужно выполнить инициализацию поточно-ориентированной. Это потому, что после инициализации все потоки, которым нужен экземпляр, должны будут ждать друг друга (и это бесполезное узкое место).
Только если ваш экземпляр имеет значение null, вызывайте синхронизированный (приватный) метод, который выполняет инициализацию; внутри этого метода проверьте еще раз , если экземпляр имеет значение null. Другой подход состоит в том, чтобы иметь закрытый внутренний класс SingletonHolder
, который содержит экземпляр, так что вы будете полагаться на загрузчик классов для выполнения поточно-ориентированной инициализации.
Однако, если вы не можете (не хотите) избегать использования синглтона, очень хорошим выбором будет перечисление с единственной определенной константой: INSTANCE;
public enum EntityManagerFactorySingleton {
INSTANCE;
// all your code -- fields, constructor, instance / static methods get in here
// you can still have the `getInstance()` static method returning INSTANCE, if you want.
}
Единственным недостатком является то, что вы не можете выполнить отложенную инициализацию для INSTANCE
, но теперь вы поточно-ориентированы и готовы к проблемам сериализации или клонирования без каких-либо усилий.