單例模式,是一種常用的軟體設計模式。通過單例模式可以保證系統中,應用該模式的類乙個類只有乙個例項。即乙個類只有乙個物件例項。
單例模式有以下特點:
(1)只能有乙個例項。
建立例項的方法有很多種,最常用的就是通過構造方法new
,通過類實現轉殖介面來轉殖乙個例項,通過反射的方法以及反序列化。既然要保證只有乙個例項,那麼就得阻斷這幾個建立例項的方法,所以單例模式的類要做到:
(2)自己建立自己的唯一例項。
既然構造方法是私有的,外界各種可能建立乙個新例項的方法都被阻斷了,那麼就只能在類的內部自己建立。
單例模式有很多種寫法,大部分寫法都或多或少有一些不足。常見的有餓漢模式以及懶漢模式
1、餓漢模式(使用靜態常量或者靜態**塊):
public class singleton
*/// 方法2
private singleton()
public static singleton getinstance()
}
優點:這種寫法比較簡單,就是在類裝載的時候就完成例項化。避免了執行緒同步問題。
缺點:在類裝載的時候就完成例項化,沒有達到延遲載入的效果。如果從始至終從未使用過這個例項,則會造成記憶體的浪費。
2、懶漢模式(非執行緒安全)
public class singleton
public static singleton getinstance()
return singleton;
}}
優點:這種寫法比較簡單,能達到延遲載入的效果。
缺點:執行緒不安全,只能在單執行緒的情況下使用,多執行緒的情況下可能那個會產生多個例項。
3、懶漢模式(執行緒安全,同步方法)
public class singleton
public static synchronized singleton getinstance()
return singleton;
}}
優點:能達到延遲載入的效果,通過對getinstance()進行執行緒同步解決了寫法2中多執行緒的情況下可能那個會產生多個例項的問題。
缺點:效率太低了,每個執行緒在想獲得類的例項時候,執行getinstance()方法都要進行同步。而其實這個方法只執行一次例項化**就夠了,後面的想獲得該類例項,直接return就行了。
4、懶漢模式(同步**塊)
public class singleton
public static singleton getinstance()
}return singleton;
}}
優點:能達到延遲載入的效果
缺點:這種同步並不能起到執行緒同步的作用。跟第2種實現方式遇到的情形一致,假如乙個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另乙個執行緒也通過了這個判斷語句,這時便會產生多個例項。
5、懶漢模式(同步**塊+雙重檢查)
public class singleton
public static singleton getinstance() }}
return singleton;
}}
達到延遲載入的效果,執行緒安全,效率高,推薦使用。
6.靜態內部類
public class singleton
private static class singletoninstance
public static singleton getinstance()
}
這種方式跟餓漢式方式採用的機制類似,但又有不同。兩者都是採用了類裝載的機制來保證初始化例項時只有乙個執行緒。不同的地方在餓漢式方式是只要singleton類被裝載就會例項化,沒有延遲載入的作用,而靜態內部類方式在singleton類被裝載時並不會立即例項化,而是在需要例項化時,呼叫getinstance方法,才會裝載singletoninstance類,從而完成singleton的例項化。達到延遲載入的效果,執行緒安全,效率高,推薦使用。
單例模式只允許建立乙個物件,因此節省記憶體,加快物件訪問速度,因此物件需要被公用的場合適合使用,如多個模組使用同乙個資料來源連線物件等等。如:
1.需要頻繁例項化然後銷毀的物件。
2.建立物件時耗時過多或者耗資源過多,但又經常用到的物件。
3.有狀態的工具類物件。
4.頻繁訪問資料庫或檔案的物件。
以下都是單例模式的經典使用場景:
1.資源共享的情況下,避免由於資源操作時導致的效能或損耗等。如上述中的日誌檔案,應用配置。
2.控制資源的情況下,方便資源之間的互相通訊。如執行緒池等。
應用場景舉例:
1.外部資源:每台計算機有若干個印表機,但只能有乙個printerspooler,以避免兩個列印作業同時輸出到印表機。內部資源:大多數軟體都有乙個(或多個)屬性檔案存放系統配置,這樣的系統應該有乙個物件管理這些屬性檔案
2. windows的task manager(任務管理器)就是很典型的單例模式(這個很熟悉吧),想想看,是不是呢,你能開啟兩個windows task manager嗎? 不信你自己試試看哦~
3. windows的recycle bin(**站)也是典型的單例應用。在整個系統執行過程中,**站一直維護著僅有的乙個例項。
4. **的計數器,一般也是採用單例模式實現,否則難以同步。
5. 應用程式的日誌應用,一般都何用單例模式實現,這一般是由於共享的日誌檔案一直處於開啟狀態,因為只能有乙個例項去操作,否則內容不好追加。
6. web應用的配置物件的讀取,一般也應用單例模式,這個是由於配置檔案是共享的資源。
7. 資料庫連線池的設計一般也是採用單例模式,因為資料庫連線是一種資料庫資源。資料庫軟體系統中使用資料庫連線池,主要是節省開啟或者關閉資料庫連線所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因為何用單例模式來維護,就可以大大降低這種損耗。
8. 多執行緒的執行緒池的設計一般也是採用單例模式,這是由於執行緒池要方便對池中的執行緒進行控制。
9. 作業系統的檔案系統,也是大的單例模式實現的具體例子,乙個作業系統只能有乙個檔案系統。
設計模式之單例模式
前一段時間買了一本秦小波寫的 設計模式之禪 網上對這書的評價很高。現在還沒有看很多,但是有些地方頗有感觸,也並不是所有的地方都能看懂,但是會慢慢研究的。自己對於設計模式的感覺就是乙個字 牛!感覺會23種設計模式並且會熟練運用的人,真的就是大師級的牛人了,設計模式是乙個專案主管或者架構師一定要會的東西...
設計模式之單例模式
package com.xie.singleton public class singleton 提供乙個共有的靜態的入口方法 public static singleton getinstance 懶漢式 延遲載入 提供乙個私有的靜態的成員變數,但不做初始化 private static sing...
設計模式之 單例模式
單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式 單件模式 使用方法返回唯一的例項 public class singleton private static singleton instance public static singleton geti...