【單例模式定義】
確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。
【關鍵點】
1.定義乙個private訪問許可權的構造方法,避免被其它類new出乙個物件。
2.自己可以new出乙個物件,其他類可以通過getinstance()方法獲得同乙個物件。
【優點】
1.由於單例模式在記憶體中只有乙個例項,減少了記憶體開支,特別是乙個物件需要頻繁地建立、銷毀時,而且建立或銷毀時效能又無法優化,單例模式的優勢就非常明顯。
2.單例模式只生成乙個例項,減少了系統的效能開銷,當乙個物件產生需要較多資源時,如讀取配置、產生其他依賴物件時,則可以通過在應用啟動的時候直接產生乙個單例物件,然後永久駐留記憶體的方式來解決。
3.單例模式可以避免對資源的多重占用,例如乙個寫檔案動作,由於只有乙個例項存在記憶體中,避免對同乙個檔案同時寫操作。
4.單例模式可以在系統設定全域性的訪問點,優化和共享資源訪問,例如乙個單例類來負責所有的資料表的對映處理。
【使用場景】
(在乙個系統中,要求類有且只有乙個物件的場景)
1.要求生成唯一序列號的環境。
2.在整個專案中需要乙個共享訪問點或共享資料。
3.建立乙個物件需要消耗的資源資源過多,如要訪問io和資料庫等資源。
4.需要定義大量的靜態常量和靜態方法(常見於工具類)的環境。(當然也可以直接宣告為static的方式)
【餓漢式】
package com.higgin.single;【懶漢式:執行緒不安全】public
class
hungrysingle ;
//通過該方法獲得例項物件
public statichungrysingle getinstance()
//類中的其它方法,盡量使static
public
static
void
dosomething()
}
package com.higgin.single;/**[ 普通懶漢式:執行緒不安全的例子 ]* 執行緒不安全的 懶漢式 單例模式 */
public
class
lazysingle ;
public staticlazysingle lazysingle=null
;
public staticlazysingle getinstance()
return
lazysingle;}}
class[ 執行結果 ]lazysingle ;
public
static lazysingle lazysingle=null
;
public
static
lazysingle getinstance() throws interruptedexception
return
lazysingle;
}}class
mythread implements runnable
} catch
(interruptedexception e)
}}public
class
test
}
其hashcode值有多處不同,說明發生了多執行緒的處理異常
【懶漢式:雙重加鎖(執行緒安全)】
/*[ 為什麼要加第乙個null判斷 ]* * 懶漢式:雙重加鎖 */
public
class
lazysingle
private staticlazysingle singleton=null
;
public staticlazysingle getinstance()}}
return
singleton;}}
加第二個null判斷很容易理解,為什麼要加第乙個null判斷呢?
對於單例設計模式,本質上要求我們只能執行一次" singleton=new lazysingle(); ",
如果沒有第乙個null判斷,所有執行緒都會來搶占鎖,搶占成功的正常執行,未成功的要進行等待,每次只能有乙個執行緒執行。
如果加上第乙個null判斷,只要執行了一次" singleton=new lazysingle(); ",後續進入該方法的執行緒,無需等待同步**塊的鎖,只要在第乙個null判斷執行結束後就可以往下走了,極大節約了效能。
[ 驗證加第乙個null判斷的效能 ]
/*[ 執行結果 ]* * 懶漢式:雙重加鎖 */
class
lazysingle
private
static lazysingle singleton=null
;
public
static
lazysingle getinstance() throws interruptedexception}}
return
singleton;
}}class
mythread implements runnable
} catch
(interruptedexception e)
}}public
class
test catch
(interruptedexception e)
}public
static
void
main(string args) throws interruptedexception
lazysingle l=lazysingle.getinstance(); //
獲取單例模式的
system.out.println("
main方法的執行緒*****=
"+l.hashcode());
long end=system.currenttimemillis();
system.
out.println("
【耗時:
"+(end-begin)+"
毫秒】"
); }
}
[ 注釋了第乙個null之後的執行結果(效能下降) ]
【靜態內部類方式:執行緒安全】
/*[ 分析 ]* * 懶漢式:靜態內部類 執行緒安全 */
public
class
lazysingle
private static classlazysinglebuilder
public staticlazysingle getinstance()
}
當getinstance()方法第一次被呼叫的時候,第一次讀取lazysinglebuilder.singleton,靜態內部類lazysinglebuilder類得到初始化,在這個類裝載並初始化的時候,會初始化它的靜態域,從而建立lazysingle的例項,由於是靜態的域,因此只會在虛擬機器裝載類的時候初始化一次,並且由虛擬機器來保證它的執行緒安全性。
(01)單例模式
單例模式讓類只能new乙個物件,使得每次從類中拿到的物件都是同乙個物件。在成員變數中建立物件 單例 餓漢式 public class demo public static demo getinstance 在需要物件的時候,再進行建立。單例 懶漢式 public class demo public ...
01 設計模式 單例模式
package com.hxh public class hungry public static hungry getinstance public static void main string args start 注意事項 變數hungry必須是 私有,靜態,不可變 構造器私有 公開的get...
01 設計模式 單例模式
package com.hxh public class hungry public static hungry getinstance public static void main string args start 注意事項 變數hungry必須是 私有,靜態,不可變 構造器私有 公開的get...