為什麼靜態內部類的單例模式是最推薦的?
如何在反射的情況下保證單例?
如何在反序列化中保證單例?
針對上述三個問題有了這篇文章,以一種循序漸進的方式,引出最後一種單例設計模式,希望對大家能夠有所幫助。
單例設計模式這種其實大家都懂,不多說,上**。
package singleton;
public class singleton1
public static singleton1 getinstance()
}
優點就是執行緒安全啦,缺點很明顯,類載入的時候就例項化物件了,浪費空間。於是乎,就提出了懶漢式的單例模式(1)懶漢式v1
public class lazysingleton1
public static lazysingleton1 getinstance()
return instance;
}
然而這一版執行緒是不安全的,於是乎為了執行緒安全,就在getinstance()方法上加synchronized修飾符,於是getinstance()方法如下所示public static synchronized lazysingleton1 getinstance()
return instance;
}
然而,將synchronized加在方法上效能大打折扣(syncrhonized會造成執行緒阻塞),於是乎又提出一種雙重校驗鎖的單例設計模式,既保證了執行緒安全,又提高了效能。雙重校驗鎖的getinstance()方法如下所示
public static lazysingleton1 getinstance()
} }
return instance;
}
(2)懶漢式v2
懶漢式v1的最後乙個雙重校驗鎖版,不管效能再如何優越,還是使用了synchronized修飾符,既然使用了該修飾符,那麼對效能多多少少都會造成一些影響,於是乎懶漢式v2版誕生。不過在講該版之前,我們先來複習一下內部類的載入機制,**如下
public class outertest
// 靜態內部類
static class staticinnertest
static void staticinnermethod()
}public static void main(string args)
}
輸出如下load outer class...
**********=分割線**********=
load static inner class...
static inner method
因此,我們有如下結論
載入乙個類時,其內部類不會同時被載入。
乙個類被載入,當且僅當其某個靜態成員(靜態域、構造器、靜態方法等)被呼叫時發生。。
基於上述結論,我們有了懶漢式v2版,**如下所示
package singleton;
public class lazysingleton2
static class singletonholder
public static lazysingleton2 getinstance()
}
由於物件例項化是在內部類載入的時候構建的,因此該版是執行緒安全的(因為在方法中建立物件,才存在併發問題,靜態內部類隨著方法呼叫而被載入,只載入一次,不存在併發問題,所以是執行緒安全的)。
另外,在getinstance()方法中沒有使用synchronized關鍵字,因此沒有造成多餘的效能損耗。當lazysingleton2類載入的時候,其靜態內部類singletonholder並沒有被載入,因此instance物件並沒有構建。
而我們在呼叫lazysingleton2.getinstance()方法時,內部類singletonholder被載入,此時單例物件才被構建。因此,這種寫法節約空間,達到懶載入的目的,該版也是眾多部落格中的推薦版本。
ps:其實列舉單例模式也有類似的效能,但是因為可讀性的原因,並不是最推薦的版本。
單例 工廠模式 內部類
設計模式 解決某類問題的乙個固定的程式設計模式,思路 23種 1.單例模式 只有乙個例項 這個類的只給提供乙個例項 public class sessionfactory 3.提供乙個靜態方法,返回私有的靜態的本類的屬性 向外界提供乙個例項 public static sessionfactory ...
單例模式 靜態內部類
靜態內部類是乙個很好的實現單例的方式 看 package cn.liz.syn public class staticinner 私有的靜態內部類 private static class inner 公共的 獲取例項的方法 public static staticinner getinstance...
單例模式和內部類
單例模式的特點 類中定義乙個無參的構造方法,並且宣告為私有 在類的內部建立該類的乙個例項物件,使用私有的靜態變數引用該例項物件 定義靜態方法返回該例項物件。靜態內部類方法內部類 靜態內部類中可以定義靜態成員和非靜態成員,如果要訪問非靜態成員,必須通過靜態內部類的物件或者物件的引用變數。在靜態方法中只...