1. 程式人生 > >什麼是單例模式?單例模式有哪些?單例模式怎麼寫?

什麼是單例模式?單例模式有哪些?單例模式怎麼寫?

單例模式

什麼是單例模式?

單例模式是一種常用的軟體設計模式。
在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個例項。即一個類只有一個物件例項

個人理解:單例模式就是同事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;  
    }  
}