設計思想學習—單例模式

單例模式

單例模式(singleton): 保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

單例模式個人感覺是最簡單的設計模式,因爲他的目的很簡單,並且沒有用到太多的面對對象的特徵,所以很簡單。
單例模式主要是爲了不要有重複的實例出現。
主要分爲了兩種:
懶漢

 public class Singleton {  
        private static Singleton instance;
        private Singleton() {} ;
        public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
        }  
    }  

Singleton通過將構造方法限定爲private避免了類在外部被實例化,在同一個虛擬機範圍內,Singleton的唯一實例只能通過getInstance()方法訪問。 當時當多線程的時候難免會出現多個實例,所以線程不安全。

惡漢

    public class Singleton {  
        private static fianl Singleton instance = new Singleton();  
        private Singleton (){}  
        public static Singleton getInstance() {  
        return instance;  
        }  
    }  

惡漢在類創建的時候就已經實例化好一個靜態的實例,而且不會被改變了,所以它天生就是線程安全。

針對懶漢的線程不安全的問題又出現了集中安全的懶漢:

  • 在getInstance()方法上加鎖
 public class Singleton {  
        private static Singleton instance;
        private Singleton() {} ;
        public static synchronized  Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
        }  
    }  

這種辦法雖然成功的解決了線程問題,但是在方法上加鎖每次都要都要同步,浪費很多性能。

  • 雙重檢查鎖定
    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;  
        }  
    }  

同樣的既然加鎖就會同步,只不過比上面那種稍好一點因爲鎖的內容越少,消耗越小。

  • 靜態內部類
    public class Singleton {  
        private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
        }  
        private Singleton (){}  
        public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
        }  
    }  

這種方法和餓漢很相似,只不過不同的是,使用了內部類,所以在類創建的時候並不會創建實例,而是在調用的時候創建實例,這種方法算是融合懶漢和餓漢的有點,同時也不會有加鎖的問題。

其實還有更好的就是使用1.5後更新的新特性,就是使用枚舉,這種方式也是最提倡的。

public enum Singleton {  
    INSTANCE;  
}  

簡單粗暴


至此五種創建型的設計模式已經全部學習完畢
分別是:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
下次將學習結構型設計模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章