設計模式之---單例模式,設計模式之---模式

來源:互聯網
上載者:User

設計模式之---單例模式,設計模式之---模式

設計模式的世界中,單例模式可能是最簡單的一種模式,雖說簡單,但想要徹底的弄明白它,還是要經曆一點點的波折。

下面我為大家慢慢道來:


在實際開發中,對於有些對象,我們只需要一個,比如線程池(thread pool),緩衝(cache),對話方塊,日誌對象,工作管理員等等。這些對象只能有一個執行個體,如果出現多個執行個體,則會導致許多問題的產生。


你可能會說,我們為什麼不用java的全域變數,多方便的。是的,但是這樣做是有缺點的,如果我們將一個對象賦值給一個全域變數,那麼我們在程式一開始就必須建立好對象,一旦這個對象非常耗費資源,而程式在執行中又一直沒有用到它,那麼這樣是非常的浪費。


單例模式,要保證一個對象只能被執行個體化一次,我們先來看一段雛形代碼:

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

在這裡,我們利用一個靜態變數來記錄Singleton類的唯一執行個體,並把構造方法設定為私人,那麼只有在Singleton類內部才可以調用此構造方法。然後我們用getInstance()方法執行個體化對象,並返回這個執行個體。如果uniqueInstance是空的,表示還沒有建立執行個體,如果不為空白,表示之前已經建立過對象,則直接跳過至return語句。


但是仔細想想,就會發現,上面的代碼是有些問題的,問題在哪裡呢?


如果我們想應用多線程,那麼如果有兩個或兩個以上的線程要執行上面這段代碼,則可能會出現產生多個執行個體對象的情況,也就是說,沒有同步機制,可能兩個線程都執行到了uniqueInstance==null的情況,那麼之後就會產生兩個object,而這樣的結果就是不對的。


這是你可能會說,給方法加synchronized關鍵字啊,是的,於是有了下面的代碼:

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

這樣,我們通過增加synchronized關鍵字到getInstance()方法中,可以使得每個線程在進入這個方法之前,要先等候別的線程離開該方法。也就是說不會有兩個線程可以同時進入該方法。


但是這樣做的問題是什嗎?仔細想想,很簡單,那就是:同步會降低效能


也就是說,我們只有第一次執行此方法的時候才需要同步,一旦設定好了uniqueInstance變數,就不再需要同步這個方法了,因為只有第一次unqueInstance==null,之後每次調用這個方法,同步都是多餘的,甚至是一種累贅。


所以,有時候要根據情況靈活的應對。


如果getInstance()的效能對應用程式不是很重要,那就什麼都別做,但是必須要知道的是,同步一個方法可能會造成程式執行的效率下降100倍,所以很多時候,我們就要重新考慮了。


當然,如果我們有時很急切的需要建立執行個體,而不用延遲執行個體化的做法,就是在靜態初始化器中建立單例,如下面的代碼:

public class Singleton {private static Singleton uniqueInstance=new Singleton();private Singleton(){}public static synchronized Singleton getInstance(){return uniqueInstance;}}

而且這段代碼是安全執行緒的。


下面我們來看單例模式的最終版:

雙重檢查加鎖,在getInstance()中減少使用同步:

利用雙重檢查加鎖(double-checked locking),首先檢查是否執行個體已經建立了,如果未建立,才進行同步,這樣,只有第一次會同步,而這正是我們想要的:

public class Singleton {private volatile static Singleton uniqueInstance;private Singleton(){}public static Singleton getInstance(){if(uniqueInstance==null){synchronized (Singleton.class){if(uniqueInstance==null){uniqueInstance = new Singleton();}}}return uniqueInstance;}}

volatile關鍵字,用來確保將變數的更新操作通知到其他線程,保證新值能立即同步到主記憶體,以及每次使用前立即從主記憶體重新整理。當把變數聲明為volatile後,編譯器與運行時都會注意到這個變數是共用的。

在這裡,volatile關鍵字確保了,當uniqueInstance變數被初始化成Singleton執行個體時,多個線程能正確的處理uniqueInstance變數。

如果效能是你關係的重點,那麼這個做法可以幫你大大減少getInstance()的時間耗費。


什是單例設計模式

java模式之單例模式:
單例模式確保一個類只有一個執行個體,自行提供這個執行個體並向整個系統提供這個執行個體。
特點:
1,一個類只能有一個執行個體
2,自己建立這個執行個體
3,整個系統都要使用這個執行個體
例: 在下面的對象圖中,有一個"單例對象",而"客戶甲"、"客戶乙" 和"客戶丙"是單例對象的三個客戶對象。可以看到,所有的客戶對象共用一個單例對象。而且從單例對象到自身的連接線可以看出,單例對象持有對自己的引用。

Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個執行個體存在。在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。一些資源管理員常常設計成單例模式。
外部資源:譬如每台電腦可以有若干個印表機,但只能有一個Printer Spooler,以避免兩個列印工作同時輸出到印表機中。每台電腦可以有若干個通訊連接埠,系統應當集中管理這些通訊連接埠,以避免一個通訊連接埠被兩個請求同時調用。內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性檔案存放系統配置。這樣的系統應當由一個對象來管理這些屬性檔案。

一個例子:Windows 資源回收筒。
在整個視窗系統中,資源回收筒只能有一個執行個體,整個系統都使用這個惟一的執行個體,而且資源回收筒自行提供自己的執行個體。因此,資源回收筒是單例模式的應用。

兩種形式:
1,餓漢式單例類
public class Singleton {

private Singleton(){}

//在自己內部定義自己一個執行個體,是不是很奇怪?
//注意這是private 只供內部調用

private static Singleton instance = new Singleton();

//這裡提供了一個供外部存取本class的靜態方法,可以直接存取
public static Singleton getInstance() {
return instance;
}
}

2,懶漢式單例類

public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton getInstance() {

//這個方法比上面有所改進,不用每次都進行產生對象,只是第一次

//使用時產生執行個體,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }

}

第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再產生了。...餘下全文>>
 
java 單例模式(單一設計模式)怎保證的只可以產生一個執行個體?更具體的解釋

我覺得這個注釋已經說得很清楚了,GOF的23種設計模式說得很清楚,單例,就是一個Class在一個Classloader中只有一個執行個體。在類中寫一個私人的構造器,那麼除了自己,在其他類中都無法建立這個類的執行個體,其中有一個靜態域也就是自己的執行個體,由自己NEW出來的,其中的可以被其他類訪問的靜態方法只是返回這個執行個體,而不會去再New,所以保證了不能再建立第二個!
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.