JAVA設計模式【二】 - 單例模式

單例模式
 
    單例模式是比較常用和容易理解的一種設計模式,目的是一個單例對象的類只允許存在一個實例。
常用的例如數據庫連接池和多線程的線程池就是單例模式的。
 
單例模式的幾種實現方式:
 
餓漢模式:
 
/**
* Created by j on 2018/3/1.
*/
public class Singleton {
    private static Singleton ourInstance = new Singleton();
 
    public static Singleton getInstance() {
        return ourInstance;
    }
 
    private Singleton() {}
}
    這種方式 因爲定義實例爲靜態的,所以在虛擬機對該類進行裝載的時候就會生成實例。屬於常用的方式,但是缺點在於如果不需要調用該實例會對內存造成浪費。
 
非線程安全-懶漢模式:
 
/**
* Created by j on 2018/3/1.
*/
public class Singleton {
    public static Singleton singleton;
 
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
 
    private Singleton() {}
}
 
顧名思義,就是在不需要該實例的時候不創建,只有在第一次用到的時候會創建該實例,但是此方式不建議使用,因爲是非線程安全的,如果多線程同時獲取實例,並且在同時驗證實例爲空時通過,會創建兩個實例。
 
線程安全-同步-懶漢模式:
 
public class Singleton {
    public static Singleton singleton;
 
    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }    
 
    private Singleton() {}
}
 
在獲取對象的實例方法上通過synchronized關鍵字爲該方法添加同步鎖,這樣可以保證只有一個線程會調用該方法,但是如果多線程同時過來時就會發生線程堵塞,造成效率性能的極度下降,所以不建議採用此方式。
 
非線程安全-同步代碼塊-懶漢模式:
/**
* Created by j on 2018/3/1.
*/
public class Singleton {
    public static Singleton singleton;
 
    public static Singleton getInstance() {
 
        if (singleton == null) {
            synchronized (Singleton.class){
                singleton = new Singleton();
            }
        }
        return singleton;
    }
 
    private Singleton() {}
}
 
當多個線程同時進入到null判斷之後,雖然鎖的是代碼塊,但是還會執行兩次實例化。
 
雙重檢查模式
/**
* Created by j on 2018/3/1.
*/
public class Singleton {
    public static Singleton singleton;
 
    public static Singleton getInstance() {
 
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
 
    private Singleton() {}
}
這樣可以保證是線程安全的。
 
靜態內部類模式
 
/**
* Created by j on 2018/3/1.
*/
public class Singleton {
 
    private Singleton() {}
 
    private static class SingletonIns{
        private static final Singleton instance = new Singleton();
    }
 
    public static Singleton getInstance() {
        return SingletonIns.instance;
    }
}
這樣與餓漢模式相似,該模式是懶加載模式,餓漢模式在類被裝載時創建實例,而該模式,只有在調用getInstance時纔會裝載靜態內部類,然後創建實例。

 

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