使用靜態內部類實現延遲載入單例模式
所謂單例模式,簡單來說,就是在整個應用中保證只有一個類的例項存在。就像是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 |
publicclassSingletonIniti{ privateSingletonIniti(){ } privatestaticclassSingletonHolder{ privatestaticfinalSingletonIniti INSTANCE=newSingletonIniti(); } publicstaticSingletonIniti getInstance(){ returnSingletonHolder.INSTANCE; } } |
當getInstance方法第一次被呼叫的時候,它第一次讀取SingletonHolder.instance,內部類SingletonHolder類得到初始化;而這個類在裝載並被初始化的時候,會初始化它的靜態域,從而建立Singleton的例項,由於是靜態的域,因此只會在虛擬機器裝載類的時候初始化一次,並由虛擬機器來保證它的執行緒安全性。
這個模式的優勢在於,getInstance方法並沒有被同步,並且只是執行一個域的訪問,因此延遲初始化並沒有增加任何訪問成本。