【Java】單例模式

一:何時用單例模式

      只實例化一個對象時。幾乎所有的系統都會用到單例模式

二:模式

  • 構造函數是私有的private

  • 產生一個靜態的私有的對象

  • 寫一個靜態的公有的方法,返回該類類型的實例化對象

三:分類:

懶漢式

  • 存在多線程同步問題,可能會存在多個ClientManager 實例對象
  • 當類第一次被加載時,不會爲ClientManager
    實例化的對象分配內存,因爲在沒調用之前根本沒有實例化,當第一次調用getInstance()時,纔會爲ClientManager
    實例化的對象分配內存,某段時間節省了內存空間
//私有的靜態成員
private static ClientManager instance = null;
// 定義私有構造方法(防止通過 new ClientManager()去實例化)
private ClientManager() {}

public static ClientManager getInstance() {
	if(instance == null) {
		synchronized(ClientManager.class){
			if(instance == null){
				instance  = new ClientManager();
			}
		}		
	}
	return instance;
}

餓漢式

  • 不存在多線程同步問題
  • 當類第一次被加載時,就會爲ClientManager 實例化的對象分配內存,某段時間浪費了內存空間
//私有的靜態成員
private static ClientManager instance = new ClientManager();
// 定義私有構造方法(防止通過 new ClientManager()去實例化)
private ClientManager() {}

public static ClientManager getInstance() {
	//返回實例化對象
	return instance;
}

四.優缺點

優點

  1. 節約系統資源,當 需要頻繁創建和銷燬的對象時單例模式無疑可以提高系統的性能
  2. 提供了對唯一實例的受控訪問

缺點

  1. 不適用於變化的對象,如果同一類型的對象總是要在不同的用例場景發生變化,單例就會引起數據的錯誤,不能保存彼此的狀態
  2. 不能被繼承,因爲構造函數是私有的,不能擴展

五.實際使用

在多線程中,線程池(數據庫連接池)就可以設置爲單例的,因爲線程池的作用就是統一管理多個線程,如果每來一個線程都去new一個新的線程池,就失去了線程池的意義。單例作用就是提供一個訪問對象的一個全局訪問點。在spring源碼中,IOC原理中如果<bean id="userservice" class="service.userService" scope="singleton"> 設置bean是singleton,bean就是單例的,默認就是單例模式,但Spring框架對單例的支持是採用單例註冊表的方式進行實現的,即將產生的bean放到一個map中,每次取時會先去註冊表檢測有沒有該bean此時,檢測的過程上了synchronized鎖,如果沒有,再creat,有直接返回。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章