1. 程式人生 > >【單例深思】靜態內部類實現詳解

【單例深思】靜態內部類實現詳解

靜態內部類實現是我個人比較推薦的,其實現如下: publicclass Singleton {     private static class SingletonHolder {         private static final Singleton INSTANCE = new Singleton();     }     private Singleton() {}     public static final Singleton getInstance() {         return SingletonHolder.INSTANCE;     } }
上面實現中,通過宣告一個靜態內部類
SingletonHolder 來持有單例 INSTANCE,在getInstance()方法中返回該例項。 我們知道,靜態內部類與非靜態內部類之間有很大的區別,非靜態內部類在編譯完成之後會隱含地儲存著一個指向建立它的外圍類的引用,但是靜態內部類卻沒有。這意味著靜態內部類的建立是不需要依賴於外圍類,它不能使用任何外圍類的非static成員變數和方法,某種程度上來說,靜態內部類可以當成是一個獨立的類。它的初始化和外部類初始化無關。 下面詳細介紹一下它是如何解決單例中的各種問題的。
首先,它是如何實現延遲載入的? 由於INSTANCE 在靜態內部類中宣告並例項化,在會引發初始化操作,
初始化階段是執行類構造器<clinit>() 方法的過程。<clinit>() 方法是由編譯器自動收集類中的所有類變數(static的賦值動作和靜態語句塊static{})塊中的語句合併產生的。因為外部類初始化不會引發靜態內部類SingletonHolder的初始化,所以只有真正呼叫getInstance()方法,執行 SingletonHolder.INSTANCE 時,才會引發靜態內部類初始化,從而完成例項化。所以,靜態內部類實現是延遲載入的。 它如何保證例項化時執行緒安全? 既然靜態內部類初始化可以當成為一個普通類的初始化,根據虛擬機器會保證一個類的
<clinit>()方法在多執行緒環境中被正確的加鎖、同步。所以,靜態內部類實現是在例項化時是執行緒安全 在其他方面,由於在讀取例項的時候不會進行同步,所以沒有效能缺陷;沒有使用 volatile ,也不依賴 JDK 版本。 總之,靜態內部類實現單例由於編寫簡單,滿足執行緒安全和延遲載入,無其他明顯缺點,是一種在工作中用的比較多的方式。