1.單例模式的定義 單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 2.單例模式的特點 單例類只能有一個實例。 單例類必須自己創建自己的唯一實例。 單例類必須給所有其他對象提供這一實例。 3.單例模式的Java代碼 單例模式分為懶漢式(需要才去創建對象)和餓漢式(創建類的實 ...
1.單例模式的定義
單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。
2.單例模式的特點
單例類只能有一個實例。
單例類必須自己創建自己的唯一實例。
單例類必須給所有其他對象提供這一實例。
3.單例模式的Java代碼
單例模式分為懶漢式(需要才去創建對象)和餓漢式(創建類的實例時就去創建對象)。
4.餓漢式
在靜態代碼塊實例對象
//在靜態代碼塊實例對象 public class Singleton {
private static Singleton singleton; static { singleton = new Singleton(); } public static Singleton getInstance() { return singleton; } private Singleton() {} }
屬性實例化對象
//餓漢模式:線程安全,耗費資源。 class SingletonHungry {
private static final SingletonHungry singletontest = new SingletonHungry(); public static SingletonHungry getSingletontest() { return singletontest; } private SingletonHungry() {} }
以上,餓漢式只要調用該類,就會實例化一個對象,非常的占用資源。
5.懶漢式
非線程安全,只有加入線程鎖(synchronized關鍵字)來保證線程安全。
//懶漢模式:需加入線程鎖(synchronized 關鍵字),保證安全 class SingletonSlacker1 {
private static SingletonSlacker1 singleton; public synchronized static SingletonSlacker1 getInstance() { if (singleton == null) { singleton = new SingletonSlacker1(); } return singleton; } private SingletonSlacker1() {} }
當然,該方式,雖然保證了線程的安全,但是只能有一個線程調用,其他線程必須等待。
線程安全:雙重檢查鎖(同步代碼塊)
//懶漢模式:加入雙重鎖 class SingletonSlacker2 {
private static SingletonSlacker2 singleton; public synchronized static SingletonSlacker2 getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new SingletonSlacker2(); } } } return singleton; } private SingletonSlacker2() { } }
6.指令重排序
其實創建一個對象,往往包含三個過程。
對於singleton = new Singleton(),這不是一個原子操作,在 JVM 中包含的三個過程。
1、給 singleton 分配記憶體
2、調用 Singleton 的構造函數來初始化成員變數,形成實例
3、將singleton對象指向分配的記憶體空間(執行完這步 singleton才是非 null 了)
針對JVM中的 指令重排序,我們可以使用 Volatile關鍵字來保證線程安全。
class SingletonVolatile{ //volatile的作用是 :保證可見性,禁止重排序,但不能保證原子性。 private volatile static SingletonVolatile singleton; public synchronized static SingletonVolatile getInstance(){ if(singleton==null){ synchronized (SingletonVolatile.class){ if (singleton==null){ singleton= new SingletonVolatile(); } } } return singleton; } private SingletonVolatile(){} }
研究不深,剛學習java,如果有什麼差錯,還望指出錯誤,共同改進。
github地址:https://github.com/Yahuiya/PersonalNotes