单例模式(比尔·皮尤的解决方案)
我正在阅读有关单例模式的wiki,我不确定我是否理解这一点:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom 正确的一部分。
所以要简单一点:为什么比尔·皮尤的解决方案比上面的例子更好?
这是因为静态类在实际使用之前没有被VM加载还是类似的东西,所以我们在转向getInstance()方法之前不会创建对象?另外,该方法线程仅在初始化对象的范围内是安全的吗?
我正在阅读有关单例模式的wiki,我不确定我是否理解这一点:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom 正确的一部分。
所以要简单一点:为什么比尔·皮尤的解决方案比上面的例子更好?
这是因为静态类在实际使用之前没有被VM加载还是类似的东西,所以我们在转向getInstance()方法之前不会创建对象?另外,该方法线程仅在初始化对象的范围内是安全的吗?
我认为Pugh先生的版本受到高度重视,因为它只在调用时执行单例的实例化,即在加载类(持有getInstance方法的类)时不执行。如果您的单例构造做了一些昂贵的事情,那么这对您来说可能是一个优势。如果你像世界上大多数人一样,他们的单例只是为了避免静态方法(而且你还没有转向依赖注入框架),那么我不会为此失眠。getInstance()
正如文章所述,Pugh 先生的方法比静态实例变量更懒惰 - 但实际上,如果 Singleton 类被加载,你无论如何都会调用 getInstance 方法。因此,作为计算机科学练习,它是有用的,但在现实世界中,它的好处是值得商榷的。
p.s. 我不太在乎布洛赫先生在这里的例子,因为使用枚举会说My Singleton IS-A枚举,这对我来说听起来不对(特别是来自一个正确地说永远不要为了实现接口只是为了获取常量的人)
JLS保证类仅在首次使用时才加载(使单例初始化延迟),并且类加载是线程安全的(也使方法线程安全)getInstance()
至于为什么线程安全
因为第一次调用 getInstance() 时,JVM 将加载持有者类。如果另一个线程同时调用 getInstance(),JVM 将不会再次加载持有者类:它将等待第一个线程完成类加载,并且在持有者类的加载和初始化结束时,两个线程都将看到持有者类正确初始化,从而包含唯一的单例实例。