何為單例模式?
通常點說就是乙個類只有乙個例項,這意味著其建構函式是私有的。
這裡讓我想到了spring ioc管理的bean,預設也是單例的。不過這裡的概念跟設計模式裡的單例不一樣,ioc裡的bean被設計成單例
在於為了servlet容器初始化spring容器時降低記憶體開銷。
spring ioc還有個關注點:被注入的bean可以是原生物件,也可以是被aop增強的**物件(也就是說在ioc容器裡的原生物件並不對外提供服務)。
單執行緒下的單例單例**一(懶漢模式),效能比餓漢的好一些 懶載入思想很多地方都用到,比如spring 、dubboz中@reference(lazy=true)
public class singleton
public static singleton getinstance()
return singleton;
}}
此為最基本的。
單例**二 (餓漢模式)
public class singleton
*/private singleton()
public static singleton getinstance()
}
以上兩段**在單執行緒下沒啥問題,但是多執行緒就不行了。
引入兩個執行緒:a和b.
當a執行緒進入**一getinstance方法,剛判斷物件為null,此時cpu切換到執行緒二執行,然後b檢測到也為null然後建立物件,過程結束後cpu切換到a繼續(因為a之前檢測為null)所以直接建立例項了。最終得到兩個例項,違反了單例原則。
繼續優化實現餓漢式,接下來加入了懶載入思想
public class singleton
private singleton()
public singleton getinstance()
}
對比之前餓漢式,都是由singleton類裝載時就初始化好了例項,而現在只有當執行getinstance方法才會去內部類獲取到例項,所以延遲了事先獲取例項體現了懶載入思想。
多執行緒下的單例
單例**三(以下只對懶漢的研究,餓漢效能差就算了)
public class singleton
public static synchronized singleton getinstance()
return singleton;
}}
該段**以同步方式實現了了執行緒安全,由於是在方法上加synchronized,所以一旦執行緒多了就阻塞等待很長時間,所以效能也偏抵。對以上**進行調優:
public class singleton
public static singleton getinstance()
}} return singleton;
}}
該**通過先判斷物件是否null,若為null則a執行緒獲取鎖b執行緒也等待,a執行完輪到b(此時物件已經不為null了),此時b進入**塊後又判斷是否為null,結果不是,最終也返回物件。這邊兩個null判斷是關鍵。這個完美實現了
思想在於:double---checked----locking 。
GOF23之單例模式
單例模式是gof23中最簡單的模式。單例的設計模式裡的出場率很高,它簡單但也有多種實現方式,也正是因為它的靈活性和重要性使喚其多次出現在面試筆試中,經常與工廠模式搭配使用。作用 保證乙個類只能有乙個例項。多次建立只會返回同乙個例項。作用範圍 如word中的工具箱,任何時候只能有乙個工具箱。大話設計模...
設計模式GOF23之單例模式
單例模式的五種方式 主要 懶漢式,餓漢式 其他 雙重檢測鎖 double checking模式 靜態內部類,列舉模式 選取時機 延時載入,占用內部資源大 靜態內部類好於懶漢 不延時載入,占用內部資源小 列舉好於餓漢 單例模式 懶漢式 author 小帆敲 public class demo01 上鎖...
設計模式GOF23之單例模式
單例模式的五種方式 主要 懶漢式,餓漢式 其他 雙重檢測鎖 double checking模式 靜態內部類,列舉模式 選取時機 延時載入,占用內部資源大 靜態內部類好於懶漢 不延時載入,占用內部資源小 列舉好於餓漢 單例模式 懶漢式 author 小帆敲 public class demo01 上鎖...