2013-07-23 51 views
1

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

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

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

首先,你的代码不能被编译。 – OQJF

回答

15

您显示的代码在技术上不是线程安全的。这种狡猾的代码经常会受到损坏。

代码应该是这样的:

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

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

在这里,我们静态初始化剂(的SingletonHolder),这将是任何线程与正确访问它之前发生,关系可以看出内分配。关于嵌套类没有什么特别的地方,它只是允许使用外部类而不需要立即构造单例对象。几乎可以肯定这是完全没有意义的,但似乎取悦一些人。

一如既往[可变]单身人士是一个非常糟糕的主意。

+0

你的代码不会被编译。 SingletonHolder没有'getInstance()'方法 – Gus

+0

不可变的单例有什么意义? – ZhongYu

+0

@ zhong.j.yu那么它不会是一个单一的任何合理的定义。单实例实现对函子(比如'Comparator's)和区分值很有用。 –

2

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

但是,您发布的代码似乎没有正确使用此模式(您不应该有空检查),并且我认为这实际上会破坏线程安全。这里有一个很好的文章,你可以阅读更多关于为什么这个模式的工作原理,以及如何正确地使用它:

Initialization-on-demand holder idiom

+2

op的代码绝对是不安全的... – assylias

+0

OP忍者编辑的问题。原文如Tom Hawtin的回答 – Affe