Java 为什么静态内部类单例线程是安全的

Java 为什么静态内部类单例线程是安全的,java,Java,正如标题所说,为什么静态嵌套类单例线程是安全的 public class Singleton { private static class SingletonHolder { public static Singleton instance; public static Singleton getInstance() { if (null == instance) { instance = new

正如标题所说,为什么静态嵌套类单例线程是安全的

public class Singleton {
    private static class SingletonHolder {
        public static Singleton instance;

        public static Singleton getInstance() {
            if (null == instance) {
                instance = new Singleton();
            }
        }
    }

    public static Singleton getInstance() {
        return SingletonHolder.getInstance();
    }
} 

您显示的代码在技术上不是线程安全的。这种狡猾的代码经常会被弄糟

代码应该如下所示:

public class Singleton  {    
    private static class SingletonHolder {    
        public static final Singleton instance = new Singleton();
    }    

    public static Singleton getInstance() {    
        return SingletonHolder.instance;    
    }    
}
在这里,我们在一个静态初始化器(属于
SingletonHolder
)中赋值,任何使用正确的before关系访问它的线程都会看到它。嵌套类没有什么特别之处,它只允许使用外部类,而无需立即构造singleton对象。几乎可以肯定,这完全是毫无意义的,但它似乎取悦了一些人


与以往一样,[mutable]单例是一个非常糟糕的想法。

它是线程安全的,因为JVM会延迟加载嵌套类

但是,您发布的代码似乎没有正确使用此模式(您不应该进行空检查),我认为这实际上破坏了线程安全。这是一篇很好的文章,您可以在其中阅读更多有关此模式工作的原因以及如何正确使用它的内容:


首先,您的代码无法编译。首先,您尝试实现的不是单例,因为您仍然可以为该类创建“n”个对象。所述类不是单例,并且能够创建多个实例的原因可能是检查错误的null检查
if(null==instance)
需要改为
if(instance==null)
。如果我错了,请纠正我。op的代码绝对不安全……op忍者编辑了这个问题。原文与Tom Hawtin的回答一样,你的代码无法编译。SingletonHolder没有
getInstance()
method不可变的singleton有什么意义?@zhong.j.yu好吧,根据任何合理的定义,它都不是singleton。单实例实现对函子(如
Comparator
s)和可分辨值很有用;单例函子只是一种性能优化,它对应用程序逻辑没有意义。@TomHawtin tackline您可以添加一个私有单例构造函数
private singleton(){}
,以完成此示例。