Замедляет ли энергозависимое использование производительность - PullRequest
0 голосов
/ 05 сентября 2018

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

public enum Singleton {
 INSTANCE 
} 

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

Хотя оба класса являются поточно-ориентированными и дают одинаковый желаемый результат. Помимо читабельности кода, есть ли какие-либо преимущества в производительности при использовании перечислений.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018
Ключевое слово

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 гарантирует, что перечисления всегда создаются только один раз. Однако преимущества ленивой инициализации теряются при таком подходе. Поскольку синхронизация не используется, этот подход будет иметь лучшую производительность, чем синхронизированный подход.

Лучший способ спроектировать одноэлементный класс - использовать метод, предложенный в этом ответе

0 голосов
/ 05 сентября 2018

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

Вы можете объявить переменную равной volatile, если она должна быть распределена между разными потоками, но она не должна быть synchronized с какой-либо другой переменной. Объявление volatile гарантирует, что каждый раз, когда поток просматривает переменную, он всегда будет видеть самое новое значение, которое было ему присвоено, даже если это значение было назначено другим потоком.

Да. volatile дорого. Было бы ошибкой использовать его, когда он вам не нужен (например, было бы ошибкой использовать его для переменной, которая не является общей, и было бы ошибкой использовать ее для общей переменной, которая уже является защищены другими средствами.)

...