定義
確保一個類只有一個實(shí)例,并提供一個全局訪問點(diǎn)
Ensure a class only has one instance, and provide a global point of access to it.
使用場景
- 必須只有一個類的一個實(shí)例,并且它必須可以從公知的接入點(diǎn)訪問客戶端
- 當(dāng)單個實(shí)例應(yīng)該通過子類化擴(kuò)展時,客戶端應(yīng)該能夠使用擴(kuò)展實(shí)例而不修改它們的代碼
典型使用場景
- 日志類
- 數(shù)據(jù)庫連接
- 文件管理器
例子
一個經(jīng)典的單例:
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
考慮到多線程:
// 1. synchronized 性能差
public class Singleton{
private static Singleton instance;
private Singleton(){}
// synchronized可以確保只能有一個線程進(jìn)入下面的程序
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
// 2. 急切創(chuàng)建實(shí)例,而不用延遲實(shí)例化的做法
public class Singleton{
// JVM加載這個類時馬上創(chuàng)建此唯一的單件實(shí)例
private static Singleton instance = new Singleton();
private Singleton(){}
public static synchronized Singleton getInstance(){
return instance;
}
}
// 3. 雙重檢查加鎖 在getInstance()中減少使用同步
public class Singleton{
// Volatile確保多線程正確地處理instance
private Volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){ // 檢查實(shí)例,如果不存在,就進(jìn)入同步區(qū)域
synchronized (Singleton.class) { // 只有第一次才徹底執(zhí)行這里的代碼
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}