2013-07-23 108 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