Ключевое слово
synchronized
по определению замедляет производительность, поскольку позволяет обрабатывать синхронизированный блок кода только одному потоку. Единственная причина использования synchronized
и volatile
для создания одноэлементного класса состоит в том, чтобы обеспечить ленивую инициализацию одного экземпляра класса.
private static volatile ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton(){}
public static synchronized ThreadSafeLazySingleton getInstance(){
if(instance == null){
instance = new ThreadSafeLazySingleton();
}
return instance;
}
Ленивая инициализация полезна, когда создание экземпляра требует много ресурсов, и вы хотите отложить создание экземпляра до последнего момента.
Можно сломать одноэлементный дизайн класса, используя Reflection
и задав частному конструктору Singleton.class.getDeclaredConstructors()
доступ к true
, используя constructor.setAccessible(true)
.
Использование enum
для разработки одноэлементного класса устраняет вышеуказанный недостаток, поскольку Java гарантирует, что перечисления всегда создаются только один раз. Однако преимущества ленивой инициализации теряются при таком подходе. Поскольку синхронизация не используется, этот подход будет иметь лучшую производительность, чем синхронизированный подход.
Лучший способ спроектировать одноэлементный класс - использовать метод, предложенный в этом ответе