使用靜態內部類實現延遲加載單例模式


所謂單例模式,簡單來說,就是在整個應用中保證隻有一個類的實例存在。就像是Java Web中的application,也就是提供瞭一個全局變量。單例模式確保某一個類隻有一個實例,而且自行實例化並向整個系統提供這個實例。這個類就稱為單例類。


單例的創建一般分為懶漢式,惡漢式,雙重鎖檢查,枚舉等,其中雙重鎖檢查隻能在jdk1.5以後才能有效,1.5以前在java對象模型中的無序寫問題不能保證。


下面就介紹使用內部類的機制來巧妙實現懶漢式單例模式的實現 :Lazy initialization holder class模式


這個模式綜合使用瞭Java的類級內部類和多線程缺省同步鎖的知識,很巧妙地同時實現瞭延遲加載和線程安全。同時不受jdk版本的影響。


內部類簡單介紹


內部類分為對象級別和類級別,類級內部類指的是,有static修飾的成員變量的內部類。如果沒有static修飾的成員變量的內部類被稱為對象級內部類。


類級內部類相當於其外部類的static成員,它的對象與外部類對象間不存在依賴關系,相互獨立,因此可直接創建。而對象級內部類的實例,是必須綁定在外部對象實例上的。類級內部類隻有在第一次被使用的時候才被會裝載。


要想很簡單地實現線程安全,可以采用靜態初始化器的方式,它可以由JVM來保證線程的安全性,如惡漢式單例,這種實現方式,會在類裝載的時候就初始化對象,有可能浪費一定的內存(假設你不需要的話),有一種方法能夠讓類裝載的時候不去初始化對象,就是采用類級內部類,在這個類級內部類裡面去創建對象實例。


代碼如下:












1


2


3


4


5


6


7


8


9


10





public class SingletonIniti {


private SingletonIniti() {


}


private static class SingletonHolder {


private static final SingletonIniti INSTANCE = newSingletonIniti();


}


public static SingletonIniti getInstance() {


return SingletonHolder.INSTANCE;


}


}



當getInstance方法第一次被調用的時候,它第一次讀取SingletonHolder.instance,內部類SingletonHolder類得到初始化;而這個類在裝載並被初始化的時候,會初始化它的靜態域,從而創建Singleton的實例,由於是靜態的域,因此隻會在虛擬機裝載類的時候初始化一次,並由虛擬機來保證它的線程安全性。


這個模式的優勢在於,getInstance方法並沒有被同步,並且隻是執行一個域的訪問,因此延遲初始化並沒有增加任何訪問成本。

0 個評論

要回覆文章請先登錄註冊