什麼是單例模式?單例模式有哪些?單例模式怎麼寫?
單例模式
什麼是單例模式?
單例模式是一種常用的軟體設計模式。
在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個例項。即一個類只有一個物件例項
個人理解:單例模式就是同事new多個一樣的物件出來。new的都是同一個。
單例模式有哪幾種?
就種數來說常用的有兩種:懶漢模式和餓漢模式。
但是寫法卻有許多種。
主要常用的:懶漢模式和餓漢模式。
不能用於多執行緒
//懶漢模式不安全
public class Dog {
private static Dog dog;
private Dog(){
}
public static Dog newInstance(){
if(dog == null){
dog = new Dog();
}
return dog;
}
}
安全版的懶漢模式,能用於多執行緒,但是效率很低。
利用鎖旗標鎖起來。程式碼如下:
public class Dog {
private static Dog dog ;
private Dog (){}
public static synchronized Dog newInstance() {
if (dog == null) {
dog = new Dog ();
}
return dog ;
}
}
餓漢模式,程式碼如下:
public class Cat {
private static Cat cat = new Cat();
private Cat(){
}
public static Cat newInstance(){
return cat;
}
}
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
這種方式同樣利用了classloder的機制來保證初始化instance時只有一個執行緒,它跟第三種和第四種方式不同的是(很細微的差別):第三種和第四種方式是隻要Singleton類被裝載了,那麼instance就會被例項化(沒有達到lazy loading效果),而這種方式是Singleton類被裝載了,instance不一定被初始化。因為SingletonHolder類沒有被主動使用,只有顯示通過呼叫getInstance方法時,才會顯示裝載SingletonHolder類,從而例項化instance。想象一下,如果例項化instance很消耗資源,我想讓他延遲載入,另外一方面,我不希望在Singleton類載入時就例項化,因為我不能確保Singleton類還可能在其他的地方被主動使用從而被載入,那麼這個時候例項化instance顯然是不合適的。這個時候,這種方式相比第三和第四種方式就顯得很合理。
列舉,程式碼如下:
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
這種方式是Effective Java作者Josh Bloch 提倡的方式,它不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件,可謂是很堅強的壁壘啊,不過,個人認為由於1.5中才加入enum特性,用這種方式寫不免讓人感覺生疏,在實際工作中,我也很少看見有人這麼寫過。
雙重校驗鎖,程式碼如下:
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}