volatile 使用会降低性能吗

Does volatile usage slow down the performance

当我读到有关使用 volatilesynchronize 关键字会降低整体性能的声明时,我正在阅读有关 volatile 的文章,因此使用以下代码来创建单例 class

public enum Singleton {
 INSTANCE 
} 

最好制作一个单例 class,其中包括一个可变实例和一个 return 该静态实例的同步方法。

尽管 classes 都是线程安全的并且给出相同的预期结果。除了代码可读性之外,使用枚举是否还有任何性能优势。

也许 volatile 并不像您认为的那样。您的问题文本看起来像是在询问在多线程环境中安全发布单例的两种不同方式。但是,这不是 volatile 的目的。 volatile 解决了一个更普遍的问题。

如果一个变量需要在不同线程之间共享,你可以声明它是volatile,但它不需要与任何其他变量是synchronizedvolatile 声明确保任何时候线程查看变量时,它总是会看到分配给它的最新值,即使该值是由其他线程分配的。

是的。 volatile 是昂贵的。在不需要时使用它是错误的(例如,在未共享的变量上使用它是错误的,在已经共享的变量上使用它是错误的通过其他方式保护。)

synchronized 关键字根据定义会降低性能,因为它只允许一个线程处理同步代码块。使用 synchronizedvolatile 创建单例 class 的唯一原因是提供 class.

的单个实例的惰性初始化
private static volatile ThreadSafeLazySingleton instance;

private ThreadSafeLazySingleton(){}

public static synchronized ThreadSafeLazySingleton getInstance(){
    if(instance == null){
         instance = new ThreadSafeLazySingleton();
    }
    return instance;
}

当实例化占用大量资源并且您想将实例的创建延迟到最后一刻时,延迟初始化很有用。

可以通过使用 Reflection 并使用 [=17= 设置私有构造函数 Singleton.class.getDeclaredConstructors() 访问 true 来打破 class 的单例设计].

使用enum设计单例class克服了上述缺点,因为Java确保枚举总是只被实例化一次。但是,这种方法失去了惰性初始化的好处。由于没有使用同步,这种方式会比synchronized方式有更好的性能。

设计单例的最佳方法 class 是使用此 answer

中建议的方法