標籤:pack 線上 single 懶漢模式 載入類 構造器 單例類 sync 一個
單例模式
單例模式就是在系統運行期間有且只有一個執行個體,且只能提供私人的構造器,保證不能隨意建立該類的執行個體。
第一種(餓漢模式)
package cn.smbms.test;public class Singleton { //定義私人存取方法 private Singleton() {} //擷取執行個體 private static Singleton singleton = new Singleton(); //提供一個供外界訪問該class的方法 public static Singleton getInstance() { return singleton; }}
上述代碼在類載入時就完成了初始化操作,故載入類較慢,但是擷取對象的速度很快,也稱餓漢模式,並且餓漢模式是在類初始化時就以及自行
執行個體化,因此不存線上程安全問題。
第二種(懶漢模式)
package cn.smbms.test;public class Singleton { //定義私人存取方法 private Singleton() {} //擷取執行個體 private static Singleton singleton; //提供一個供外界訪問該class的方法 public synchronized static Singleton getInstance() { if(singleton==null) { singleton= new Singleton(); } return singleton; }} 上面第二中形式是lazy initialization, 也就是說第一次調用時初始Singleton,以後就不用再產生了。注意到lazy initialization 形式中的synchronized,這個synchronized很重要, 如果沒有synchronized,那麼使用getInstance ()是有可能得到多個Singleton ,這種在類載入時不建立執行個體,採用消極式載入的方式,在運行調用時建立執行個體,也稱
懶漢模式,即在調用方式時才擷取執行個體。 但在實際開發中,會遇到以下應用情境:執行個體化單例類很消耗資源,我們希望可以要吃載入,即不想讓它在類載入時就執行個體化,那如何處理呢?如下
package cn.smbms.test;public class Singleton { //定義私人存取方法 private Singleton() {} //擷取執行個體 private static Singleton singleton; public static class SingletionHelper{ private static Singleton INSTANCE=new Singleton(); } public static Singleton getInstance() { singleton= SingletionHelper.INSTANCE; return singleton; } public static Singleton test() { return singleton; }}
上述中,同樣利用了classloder的機制來保證初始化instance只有一個線程,但是跟之前的方式略有不同。按照之前的方式只要singleton類被裝載了
,那麼singleton就會被執行個體化,並沒有達到lazy loading的效果。而現在這種靜態內部的方式時:singleton被裝載了,卻不一定被初始化原因在於沒有主
動調用getInstance()方法。
小結
- 懶漢:類載入時不建立執行個體,因此類載入速度快,但運行速度較慢,具備消極式載入的特性,但是又不存線上程安全問題
- 餓漢:類載入時完成初始化,所以類載入慢,但擷取對象速度快
- 懶漢是“時間換空間”,餓漢就是“空間換時間”
單例模式(singleton)