餓漢一
/*
餓漢式優點:①寫法簡單②執行緒安全的
缺點:還沒被呼叫就物件就被載入了,不夠節約
*/public
class
singleton
public
static singleton getinstance()
/* 測試方法用於證明餓漢單例模式下fianl修飾單例物件的作用
注意必須是餓漢式,懶漢式不考慮使用fianl
以下的測試值是在沒有使用final的情況下的值
*/public
static
void
main
(string[
] args)
throws exception
}}
餓漢二
/*
注意:還可以使用使用**塊,意義是如果類中單例物件的建立需要引用一些其他各種型別的變數,甚至這些變數的值都在配置檔案中
此時用靜態**塊可以很好的解決問題,此時靜態**塊的意義就是在增加額外屬性的情況系成功建立單例物件
resourceutils是用來模擬一類協助單例資源建立的資源,雖然從**來看長得像懶漢式,但實際是餓漢式
因為在類載入期間,遠遠早於呼叫getbigsources()之前,singleton2就已經指向單例物件了,不為null了
補充:類路徑下singlton.properties下有儲存著單例物件的建立需要引用一些其他各種型別的變數
*/public
class
singleton2
//2 宣告靜態最終物件型屬性;
static
catch
(ioexception e)
}public
static singleton2 getinstance()
}
懶漢一:標準的懶漢模式
//標準的懶漢式,也是不安全的(包含測試方法,可以證明執行緒不安全)
public
class
singleton
public
static
final singleton getinstance()
catch
(interruptedexception e)
datasources =
newsingleton()
;return datasources;
}return datasources;
}//執行緒安全測試
public
static
void
main
(string[
] args)
throws executionexception, interruptedexception };
executorservice service = executors.
newfixedthreadpool(2
);future
f1 = service.
submit
(singletoncallable)
; future
f2 = service.
submit
(singletoncallable)
; singleton singleton1 = f1.
get();
singleton singleton2 = f2.
get();
system.out.
println
(singleton1)
; system.out.
println
(singleton2)
; system.out.
println
(singleton1 == singleton2);}
}
懶漢二,double check解決懶漢式執行緒安全問題
public
class
singleton
/* 1、如果把synchronized加到getdateasource方法中,那麼多執行緒併發呼叫n次該方法只有
一次null的情況,而只對這一種情況使得n次呼叫執行緒全部要同步,程式執行效率自然會很低
2、這樣我們在單例資源singleton不為null時再呼叫同步**塊,但在高併發環境下一瞬間
多個執行緒湧入了if(singleton == null)**塊中,在該if塊的同步塊協調下同步建立
和湧入執行緒數一樣多的資源,那這就不叫單例模式了
3 上述問題的解決方案是在同步**塊內在次singleton判斷是否為null,singleton
為null才進行建立且僅建立一次,不為null直接返回先前if塊第乙個執行緒建立的
*/private
static
final singleton getinstance()
catch
(interruptedexception e)
synchronized
(singleton.
class
)return singleton;}}
return singleton;
}//執行緒安全測試
public
static
void
main
(string[
] args)
throws executionexception, interruptedexception };
executorservice service = executors.
newfixedthreadpool(2
);future
f1 = service.
submit
(singletoncallable)
; future
f2 = service.
submit
(singletoncallable)
; singleton singleton1 = f1.
get();
singleton singleton2 = f2.
get();
system.out.
println
(singleton1)
; system.out.
println
(singleton2)
; system.out.
println
(singleton1 == singleton2);}
}
懶漢三,靜態類實現,該實現方法的懶漢式和餓漢式一樣,天生就沒有執行緒安全問題
//標準懶漢式單例模式(靜態內部類完成單例模式)
//原理:類裝載時內部類(靜態內部類)不受影響(這是jvm的內部類的載入延遲機制)但是當呼叫靜態內部類的屬性或方法時才會
//載入且只載入一次,這樣的機制是無視於執行緒的(類載入期間不考慮執行緒),且還能實現懶載入;
class
innerdatasources
//寫乙個內部具有innerdatasources例項的物件
private
static
class
innerdsinstance
public
static innerdatasources getdatesource()
}
餓漢四:列舉類實現,列舉的物件本來就是內部限定的那幾個,我們在列舉類內部只設定乙個物件就成了單例模式了
//列舉實現單例模式
enum singledemo
}
為什麼懶漢式單例模式推薦加final? 面試官系統之設計模式(單例模式)
單例模式 顧名思義就是只能有乙個,不能在出現第二個。就如同地球上沒有兩片完全一模一樣的樹葉一樣。程式猿的角度理解 乙個類有且只能有乙個例項,不能出現第二個,並且整個專案系統中都能訪問該例項。面試官 為啥不能出現第二個?程式猿 這個面試官是笨蛋,出現第二個那就不叫單例模式了,那至少得叫雙例模式,是吧?...
看完這篇單例模式,終於敢和面試官對線了
三 推 列舉模式 四 推 holder模式 五 總結 不想看過程的可以直接看結果 執行緒安全 懶載入反射破壞 餓漢模式 類載入就建立物件確保執行緒安全 立即載入 能避免懶漢模式 synchronized synchronized對方法加鎖 懶載入不能避免 雙重檢測鎖 volatile jdk 1.5...
滴滴面試官 如何實現乙個執行緒安全的單例模式
單例模式作為最常見的設計模式,有很多實現方式,今天介紹一下單例模式相關的內容。從字面上理解,單例模式需要確保乙個類只有乙個物件。比如執行緒池 快取 日誌物件 印表機驅動物件 顯示卡驅動物件等,這些類的物件往往只需要乙個例項就可以。如果乙個類的物件需要被頻繁建立,那麼也會需要頻繁gc,單例模式就可以解...