【設計模式】—-(1)單例模式(建立型)
概念: java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裡主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。 單例模式有以下特點: 1、單例類只能有一個例項。 2、單例類必須自己建立自己的唯一例項。 3、單例類必須給所有其他物件提供這一例項。
單例模式確保某個類只有一個例項,而且自行例項化並向整個系統提供這個例項。在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個印表機,但只能有一個Printer
Spooler,以避免兩個列印作業同時輸出到印表機中。每臺計算機可以有若干通訊埠,系統應當集中管理這些通訊埠,以避免一個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。
一、懶漢式單例
- //懶漢式單例類.在第一次呼叫的時候例項化自己
- publicclass Singleton {
- private Singleton() {}
- privatestatic Singleton single=null;
- //靜態工廠方法
- publicstatic Singleton getInstance() {
- if (single == null) {
-
single = new Singleton();
- }
- return single;
- }
- }
(事實上,通過Java反射機制是能夠例項化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。)
但是以上懶漢式單例的實現沒有考慮執行緒安全問題,它是執行緒不安全的,併發環境下很可能出現多個Singleton例項,要實現執行緒安全,有以下三種方式,都是對getInstance這個方法改造,保證了懶漢式單例的執行緒安全,如果你第一次接觸單例模式,對執行緒安全不是很瞭解,可以先跳過下面這三小條,去看餓漢式單例,等看完後面再回頭考慮執行緒安全的問題:
1、在getInstance方法上加同步
[java] view plain copy print?- publicstaticsynchronized Singleton getInstance() {
- if (single == null) {
- single = new Singleton();
- }
- return single;
- }
2、雙重檢查鎖定
- publicstatic Singleton getInstance() {
- if (singleton == null) {
- synchronized (Singleton.class) {
- if (singleton == null) {
- singleton = new Singleton();
- }
- }
- }
- return singleton;
- }
3、靜態內部類
[java] view plain copy print?- publicclass Singleton {
- privatestaticclass LazyHolder {
- privatestaticfinal Singleton INSTANCE = new Singleton();
- }
- private Singleton (){}
- publicstaticfinal Singleton getInstance() {
- return LazyHolder.INSTANCE;
- }
- }
二、餓漢式單例
[java] view plain copy print?- //餓漢式單例類.在類初始化時,已經自行例項化
- publicclass Singleton1 {
- private Singleton1() {}
- privatestaticfinal Singleton1 single = new Singleton1();
- //靜態工廠方法
- publicstatic Singleton1 getInstance() {
- return single;
- }
- }
三、登記式單例(可忽略)
[java] view plain copy print?- //類似Spring裡面的方法,將類名註冊,下次從裡面直接獲取。
- publicclass Singleton3 {
- privatestatic Map<String,Singleton3> map = new HashMap<String,Singleton3>();
- static{
- Singleton3 single = new Singleton3();
- map.put(single.getClass().getName(), single);
- }
- //保護的預設構造子
- protected Singleton3(){}
- //靜態工廠方法,返還此類惟一的例項
- publicstatic Singleton3 getInstance(String name) {
- if(name == null) {
- name = Singleton3.class.getName();
- System.out.println("name == null"+"--->name="+name);
- }
- if(map.get(name) == null) {
- try {
- map.put(name, (Singleton3) Class.forName(name).newInstance());
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- return map.get(name);
- }
- //一個示意性的商業方法
- public String about() {
- return"Hello, I am RegSingleton.";
- }
- publicstaticvoid main(String[] args) {
- Singleton3 single3 = Singleton3.getInstance(null);
- System.out.println(single3.about());
- }
- }
登記式單例實際上維護了一組單例類的例項,將這些例項存放在一個Map(登記薄)中,對於已經登記過的例項,則從Map直接返回,對於沒有登記的,則先登記,然後返回。
這裡我對登記式單例標記了可忽略,我的理解來說,首先它用的比較少,另外其實內部實現還是用的餓漢式單例,因為其中的static方法塊,它的單例在類被裝載的時候就被例項化了。
餓漢式和懶漢式區別
從名字上來說,餓漢和懶漢,
餓漢就是類一旦載入,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,
而懶漢比較懶,只有當呼叫getInstance的時候,才回去初始化這個單例。
另外從以下兩點再區分以下這兩種方式:
1、執行緒安全:
餓漢式天生就是執行緒安全的,可以直接用於多執行緒而不會出現問題,
懶漢式本身是非執行緒安全的,為了實現執行緒安全有幾種寫法,分別是上面的1、2、3,這三種實現在資源載入和效能方面有些區別。
2、資源載入和效能:
餓漢式在類建立的同時就例項化一個靜態物件出來,不管之後會不會使用這個單例,都會佔據一定的記憶體,但是相應的,在第一次呼叫時速度也會更快,因為其資源已經初始化完成,
而懶漢式顧名思義,會延遲載入,在第一次使用該單例的時候才會例項化物件出來,第一次呼叫時要做初始化,如果要做的工作比較多,效能上會有些延遲,之後就和餓漢式一樣了。
至於1、2、3這三種實現又有些區別,
第1種,在方法呼叫上加了同步,雖然執行緒安全了,但是每次都要同步,會影響效能,畢竟99%的情況下是不需要同步的,
第2種,在getInstance中做了兩次null檢查,確保了只有第一次呼叫單例的時候才會做同步,這樣也是執行緒安全的,同時避免了每次都同步的效能損耗
第3種,利用了classloader的機制來保證初始化instance時只有一個執行緒,所以也是執行緒安全的,同時沒有效能損耗,所以一般我傾向於使用這一種。
什麼是執行緒安全?
如果你的程式碼所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。
或者說:一個類或者程式所提供的介面對於執行緒來說是原子操作,或者多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題,那就是執行緒安全的。
應用
以下是一個單例類使用的例子,以懶漢式為例,這裡為了保證執行緒安全,使用了雙重檢查鎖定的方式:
[java] view plain copy print?相關推薦
【設計模式】—-(1)單例模式(建立型)
概念: java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裡主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。 單例模式有以下特點: 1、單例類只能有一個例項。 2、單例類必須自己建立自己的唯一例項。 3、單例類必須給所有其他物件提供這一例項。
【原】從頭學習設計模式(一)——單例模式
一、引入 單例模式作為23種設計模式中的最基礎的一種模式,在平時開發中應用也非常普遍。到底哪些類應該設計成單例的呢,我們來舉個最通俗的例子。在一個父容器中單擊某個選單項開啟一個子視窗,如果不使用單例又沒有作選單項的可用控制的話,每次單擊選單項都會開啟一個新視窗。這不僅會浪費記憶體資源,在程式邏輯
23種設計模式(1)-單例模式
如果 static 拓展 銷毀 jvm垃圾收集器 單例類 不為 全局 返回值 定義: 單例模式,是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個實例。即一個類只有一個對象實例。 特點:
設計模式(1)----單例模式
內存 內部 gin strong 系統 方法 main 重新 out 簡介: 單例模式(Singleton)是一種常用的軟件設計模式,在它的核心結構中只包含一個被稱為單例的特殊類。 定義: 確保一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 單例模式 單例模式
android開發學習 ------- 【轉】 android中的單例模式 (詳解)
lan post tail -- and 使用 href details android開發 https://blog.csdn.net/u011418943/article/details/60139644 這篇文章 前因後果 都說出來了 ,值得學習。 htt
設計模式(1)——單例模式
虛擬 span 源碼 加載 定義 實例變量 不能 內存 而且 在Java開發過程中,很多場景下都會碰到或要用到單例模式,在設計模式裏也是經常作為指導學習的熱門模式之一,相信每位開發同事都用到過。我們總是沿著前輩的足跡去做設定好的思路,往往沒去探究為何這麽做,所以這篇文章對單
java設計模式---(1)單例模式
單例模式 定義: 確保一個類只有一個例項, 而且自行例項化並向整個系統提供這個例項 保證只有一個例項,只能是不讓外面訪問的類的構造方法,所以就構造方法寫成私有的,向整個系統提供一個例項那麼就只能定義一個static的例項返回回去了,所以程式碼可以這樣寫: public class Sin
golang設計模式(1)單例模式
做軟體開發工程師兩三年了,接觸到的第一種設計模式就是單例模式,記得當年第一份工作第一個任務就是用C語言寫一個網路抓包的工具。那時候坐旁邊的同事就問,你們兩寫的這個工具有用到什麼設計模式嗎?當時一臉懵,設計模式是個什麼東西,那時候他說計算機專業有學過,但是看公司版
java設計模式(1/23)-單例模式(Singleton pattern)
java建立型模式之一: 單例模式(Singleton pattern) 什麼是設計模式? 是一套被反覆使用、多人知曉的、經過分類編目的程式碼設計經驗的總結。 使用設計模式是為了可重用程式碼,讓程式碼更容易被他人理解、保證程式碼的可靠性。 有些物件我們只需要一個,比如:
設計模式(1)單例模式
**剛接觸設計模式的時候感覺很高大上的感覺,老師怎麼寫程式碼,就怎麼寫,沒有徹底的領會設計模式的深層次的思想。藉著複習的時間總結一下。** 1. 介紹:設計模式其實就是一種反覆使用的,多數人知曉的,經過分類編輯的程式碼設計經驗的總結。它停留在思想和經驗的層面
設計模式(四)---單例模式
由於 div 懶漢式 其它 ins class single sin pub 1、簡介 作為對象的創建模式,單例模式確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例,這個類稱為單例類 2、單例模式有以下三個特點 2.1、單例類只能有一個實例
設計模式(一)單例模式
分享 公有 交互 線程 加鎖 解決 操作 編譯 進入 1.單例模式(Singleton):由於某種需要,要保證一個類在程序的生命周期中只有一個實例,並提供一個該實例的全局訪問方法。 2.單例模式(Singleton)結構圖: Singleton類,定義了一個GetInst
Java 設計模式系列(五)單例模式
重要 理解 iat 版本 ide 默認 ces 內部實現 成功 Java 設計模式系列(五)單例模式 單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 一、懶漢式單例 /** * 懶漢式單例類.在第一次調用的時候實例化自己 * 1. 構造器私
跟著別人學設計模式-----(一)單例模式詳解
作者:zuoxiaolong8810(左瀟龍),轉載自:http://www.cnblogs.com/zuoxiaolong/p/pattern2.html 上一章
常用的軟體設計模式(一)單例模式
單例模式:即一個類只有一個例項,在類裡自己建立自己的例項。 優點: (1)單例模式會阻止其他物件例項化其自己的單例物件的副本,從而確保所有物件都訪問唯一例項。 (2)因為類控制了例項化過程,所以類可以靈活更改例項化過程。尤其是在C++中,每次new都要delete,而是用單例模式可以避免
設計模式(5)單例模式
模式介紹 單例模式是一種建立型設計模式,其中一個類只保證只有一個例項,該例項可以全域性訪問。 這意味著該模式強制特定物件不具有可訪問的建構函式,並且對該物件執行的任何訪問都是在該物件的同一例項上執行的。 示例 我們模擬一下餐館裡用於通知上菜鈴鐺,它在櫃檯上只有一個。 下面程式碼中syncRoot是為
設計模式(一)單例模式詳解
愉快的開始自己的技術積累 ,設計模式中使用最普遍的單例模式開始; 設計模式中最為大家熟悉的必須是單例模式,專案中 必須 使用到的套路。首先陳述下我對 框架,模式的一些理解。 從學校出來,開始面試的時候張口框架,閉口模式,真的問道什麼是框架,我只能死鴨子嘴硬的強調 MVC ,
PHP設計模式(一)——單例模式(Singleton Pattern)
PHP設計模式(一)——單例模式(Singleton Pattern) 單例模式(Singleton Pattern):顧名思義,就是隻有一個例項。作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。 (一)為
go 設計模式(一)單例模式
go 的單例模式寫法比較簡單,可以通過sync.Once來輔助。 type Singleton struct { name string } var ( once sync.Once instance *Singleton ) func New()
設計模式一(php示例 單例模式和工廠模式)
所謂的設計模式,就是具有多年開發經驗的人,在實際工作中為了解決某一種需求,而形成的一套程式碼方案。 1.單例模式: 單例模式:所謂的單例模式就是單一的例項。通過一個類永遠只能獲取一個物件。 基本的實現思路:單例模式要求類能夠有返回物件一個引用(永遠是同一個)和一個獲得該例項的方法(必