(如有誤解請指出,感激不盡)
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的乙個類只有乙個例項。即乙個類只有乙個物件例項。
在某些場景下,我們可能只需要建立乙個例項,並且確保其他所有的物件訪問時都是這乙個例項,然後利用這個例項來控制整個系統。
適用場景
windows的任務管理器(task manager)。
windows的**站(recycle bin)。
外部印表機的管理:當一台電腦連線多個印表機的時候,也只有乙個列印後台處理服務(printerspooler),以避免多個印表機同時列印同乙個檔案。
部分軟體的一些屬性檔案的存放和呼叫,用乙個物件來統一管理。
目標:保證乙個類中只有乙個例項。
思路:外部不可建立單例類的例項物件,單例類的構造方法必須自己定義為私有。
單例類必須自己建立自己的唯一例項。
在單例類提供乙個靜態方法,在呼叫該方法時返回給其他物件唯一例項。
餓漢式:單例例項在載入類的時候就建立。
public
class
singletonhungary
// 私有化單例類構造器
public
static singletonhungary getinstance()
}
優點:在類載入的時候就完成了例項建立,避免了多執行緒同步的問題。執行緒安全,執行效率高。
缺點:只要載入了該類,例項物件就建立了。資源效率不高,而且可能getinstance()永遠不會執行使用,造成資源的浪費。
懶漢式:在需要時建立單例例項。
public
class
singletonlazy
// 私有化單例類構造器
public
static singletonlazy getinstance()
return instance;
//訪問該靜態方法時返回單例類例項
}}
優點:資源利用率高,避免了在使用該類其他靜態方法或載入該類時創造例項。起到了懶載入(lazy loading)的作用。在單執行緒下安全。
缺點:在多個執行緒同時訪問到該類getinstance()方法時,可能會同時生成多個例項,與我們的目的衝突。
懶漢式(嘗試解決):針對多個執行緒同時訪問產生多個例項的情況做調整優化。
public
class
singletonlazy
// 私有化單例類構造器
public
static singletonlazy getinstance()
}return instance;
//返回單例類例項
}}
這種情況看似利用synchronized()方法解決了多執行緒同步的問題,但其實和第2種情況一樣,如果同時有多個執行緒進入到if (instance == null)這裡,即使下面的內容加了鎖,已經同時進入的執行緒還是會挨個執行建立例項,產生多個例項。
這種方法並不能解決執行緒不安全的問題,不可用
懶漢式(執行緒安全版本):
public
class
singletonlazy
// 私有化單例類構造器
public
static singletonlazy getinstance()
}return instance;
//返回單例類例項
}}
懶漢式(執行緒安全改良版):雙重檢測
public
class
singletonlazy
// 私有化單例類構造器
public
static singletonlazy getinstance()
}}return instance;
//返回單例類例項
}}
優點:保證了單例的前提下提高了執行效率,執行緒安全且效率較高。
缺點:可能會產生重排序問題。
理解重排序:
筆者認為這篇部落格寫的非常詳細,讀者可自行跳轉理解重排序問題,本文不再過多闡述。
懶漢式(執行緒安全終極版):volatile關鍵字
volatile關鍵字簡直是為了這類問題量身定做的。**如下
public
class
singletonlazy
// 私有化單例類構造器
public
static singletonlazy getinstance()
}}return instance;
//返回單例類例項
}}
懶漢式:利用靜態內部類實現執行緒安全的延遲載入
public
class
singletonlazy
private
singletonlazy()
public
static singletonlazy getinstance()
}
優點:資源利用率高,而且執行緒安全。執行緒安全原理和餓漢式相似。不再過多闡述。
缺點:第一次載入時稍慢。
列舉:
public
enum singletonenum
public
static
void
main
(string[
] args)
}
列舉的建立由jvm保證,所以不會產生併發問題,構造器自動私有,外部不能建立只能引用。
列舉的其餘特性筆者暫時不夠了解,不在此多做介紹。
本文介紹了餓漢式、多種懶漢式和列舉等單例模式的常用寫法。在懶漢式中指出了一些常見的雷區。
最後,推薦使用的幾種方法為:餓漢式、懶漢式(執行緒安全最終版,含volatile關鍵字)、懶漢式(靜態內部類方法)、列舉。
關於單例的一點自我理解
單例,個人理解就是乙個model類,例項,必須乙個類只有乙個例項,他的宗旨是物件只建立一次。意思就是,用類建立物件的時候,先判斷物件是否存在,如果存在就用已有的不再建立新的,如果沒有就建立新的物件。一般程式執行起來只第一次建立好了直到程式退出結束之間,這個單例都一直存在,單例是一直在用物件在操作。所...
對單例模式的理解
單例模式的三個特點 1 構造方法私有化 2 例項化的變數引用私有化 3 獲取例項的方法共有 什麼是單例 確保這個類在記憶體中只會存在乙個物件,而且自行例項化並向整個應用系統提供這個例項。應用的場景 建立乙個物件會消耗過多的資源,比如訪問io和資料庫 有哪幾種方式 推薦用靜態內部類或加了volatil...
單例模式的一點小見解
還是很心煩,一面試就問單例模式,單例模式的。那麼只能看看啥是單例模式 當這個類的物件在多個地方建立的時候,使得內部的方法多次呼叫,但是希望只要乙個物件操作這個方法,或者不希望多個地方同時呼叫這個方法,需要保持這個方法的單一性質,就用單利模式吧。那麼單例模式怎麼實現的呢,關於這個網上有2種,3種,5種...