建立型模式————單例模式
這個模式應該是大家使用的最多的模式了,也是瞭解最多的模式吧。這裡我來說下我對這個模式的理解吧
1由來
對於系統中的某些類來說,只有一個例項很重要,例如,有很多首歌要播放,如果同時開兩個播放器,會導致兩首歌同時播放,造成音樂變噪音了這個時候就只能有一個播放器了。
那 如何保證一個類只有一個例項並且這個例項易於被訪問呢?定義一個全域性變數可以確保物件隨時都可以被訪問,但不能防止我們例項化多個物件。一個更好的解決辦法是讓類自身負責儲存它的唯一例項。這個類可以保證沒有其他例項被建立,並且它可以提供一個訪問該例項的方法。
2定義
3程式碼的實現
1、餓漢式(靜態常量)[可用]
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
優點:這種寫法比較簡單,就是在類裝載的時候就完成例項化。避免了執行緒同步問題。
缺點:在類裝載的時候就完成例項化,沒有達到Lazy Loading的效果。如果從始至終從未使用過這個例項,則會造成記憶體的浪費。
2、餓漢式(靜態程式碼塊)[可用]
public class Singleton {
private static Singleton instance;
static {
instance = new Singleton();
}
private Singleton() {}
public Singleton getInstance() {
return instance;
}
}
這種方式和上面的方式其實類似,只不過將類例項化的過程放在了靜態程式碼塊中,也是在類裝載的時候,就執行靜態程式碼塊中的程式碼,初始化類的例項。優缺點和上面是一樣的。
3、懶漢式(執行緒不安全)[不可用]
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
這種寫法起到了Lazy Loading的效果,但是隻能在單執行緒下使用。如果在多執行緒下,一個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以在多執行緒環境下不可使用這種方式。
4、懶漢式(執行緒安全,同步方法)[不推薦用]
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
解決上面第三種實現方式的執行緒不安全問題,做個執行緒同步就可以了,於是就對getInstance()方法進行了執行緒同步。
缺點:效率太低了,每個執行緒在想獲得類的例項時候,執行getInstance()方法都要進行同步。而其實這個方法只執行一次例項化程式碼就夠了,後面的想獲得該類例項,直接return就行了。方法進行同步效率太低要改進。
5、懶漢式(執行緒安全,同步程式碼塊)[不可用]
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
singleton = new Singleton();
}
}
return singleton;
}
}
由於第四種實現方式同步效率太低,所以摒棄同步方法,改為同步產生例項化的的程式碼塊。但是這種同步並不能起到執行緒同步的作用。跟第3種實現方式遇到的情形一致,假如一個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個執行緒也通過了這個判斷語句,這時便會產生多個例項。
6、雙重檢查[推薦用]
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Double-Check概念對於多執行緒開發者來說不會陌生,如程式碼中所示,我們進行了兩次if (singleton == null)檢查,這樣就可以保證執行緒安全了。這樣,例項化程式碼只用執行一次,後面再次訪問時,判斷if (singleton == null),直接return例項化物件。
優點:執行緒安全;延遲載入;效率較高。
7、靜態內部類[推薦用]
public class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
這種方式跟餓漢式方式採用的機制類似,但又有不同。兩者都是採用了類裝載的機制來保證初始化例項時只有一個執行緒。不同的地方在餓漢式方式是隻要Singleton類被裝載就會例項化,沒有Lazy-Loading的作用,而靜態內部類方式在Singleton類被裝載時並不會立即例項化,而是在需要例項化時,呼叫getInstance方法,才會裝載SingletonInstance類,從而完成Singleton的例項化。
類的靜態屬性只會在第一次載入類的時候初始化,所以在這裡,JVM幫助我們保證了執行緒的安全性,在類進行初始化時,別的執行緒是無法進入的。
優點:避免了執行緒不安全,延遲載入,效率高。
8、列舉[推薦用]
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
藉助JDK1.5中新增的列舉來實現單例模式。不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件。可能是因為列舉在JDK1.5中才新增,所以在實際專案開發中,很少見人這麼寫過。
優點:系統記憶體中該類只存在一個物件,節省了系統資源,對於一些需要頻繁建立銷燬的物件,使用單例模式可以提高系統效能。
缺點:當想例項化一個單例類的時候,必須要記住使用相應的獲取物件的方法,而不是使用new,可能會給其他開發人員造成困擾,特別是看不到原始碼的時候。
4模式的優點
- 提供了對唯一例項的受控訪問。因為單例類封裝了它的唯一例項,所以它可以嚴格控制客戶怎樣以及何時訪問它,併為設計及開發團隊提供了共享的概念。
- 由於在系統記憶體中只存在一個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷燬的物件,單例模式無疑可以提高系統的效能。
- 允許可變數目的例項。我們可以基於單例模式進行擴充套件,使用與單例控制相似的方法來獲得指定個數的物件例項。
- 由於單例模式中沒有抽象層,因此單例類的擴充套件有很大的困難。
- 單例類的職責過重,在一定程度上違背了“單一職責原則”。因為單例類既充當了工廠角色,提供了工廠方法,同時又充當了產品角色,包含一些業務方法,將產品的建立和產品的本身的功能融合到一起。
- 濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位;現在很多物件導向語言(如Java、C#)的執行環境都提供了自動垃圾回收的技術,因此,如果例項化的物件長時間不被利用,系統會認為它是垃圾,會自動銷燬並回收資源,下次利用時又將重新例項化,這將導致物件狀態的丟失。
6應用的場景
相關文章
- 設計模式-建立型-單例模式設計模式單例
- 設計模式(一)建立型之單例模式設計模式單例
- 建立型模式:單例模式模式單例
- 建立者模式之單例模式模式單例
- 建立型模式-單例模式-工廠模式模式單例
- Java設計模式——單例模式(建立型模式)Java設計模式單例
- 建立型模式之單例模式與工廠模式(一)模式單例
- 設計模式(三)----建立型模式之單例模式(一)設計模式單例
- 設計模式--單件模式Singleton(建立型)設計模式
- 如何建立完美的單例模式?單例模式
- Singleton(單例)——物件建立型模式單例物件模式
- 單例模式 2中建立方法單例模式
- 單例模式單例模式
- 設計模式-單例模式設計模式單例
- [設計模式] 單例模式設計模式單例
- 設計模式 —— 單例模式設計模式單例
- 設計模式(單例模式)設計模式單例
- 創造模式 單例模式模式單例
- 設計模式——單例模式設計模式單例
- 設計模式--單例模式設計模式單例
- javascript 模式(2)——單例模式JavaScript模式單例
- 設計模式 單例模式設計模式單例
- 設計模式-單例模式、多例模式設計模式單例
- 建立型:工廠模式-簡單工廠模式
- 建立型-單例單例
- 初探Java設計模式1:建立型模式(工廠,單例等)Java設計模式單例
- Python 建立單例模式的三種方式Python單例模式
- Python建立單例模式的5種方法Python單例模式
- 設計模式-單例模式,觀察者模式設計模式單例
- 設計模式一(單例模式)設計模式單例
- 設計模式之☞單例模式設計模式單例
- Java設計模式–單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例
- js設計模式--單例模式JS設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- 設計模式之單例模式設計模式單例
- Java設計模式【單例模式】Java設計模式單例