PS:這是一個(gè)小白的學(xué)習(xí)記錄之路。大神看見不要笑,獅虎看見不要生氣的哈。
題目:?jiǎn)卫J降膶?shí)現(xiàn)方式
解決思路:獅虎說不知道就要問度娘(PS:獅虎,不要打了,疼···我真的不知道單例)
解決步驟:獅虎說不知道就要多學(xué)習(xí)(PS:我認(rèn)真的抄了一遍,獅虎,我真的很認(rèn)真的抄了~)
答案:maybe~可能大概,獅虎·····別·····打·····我
首先,對(duì)于不懂什么是單例的我來說,java的單例模式是一種常見的設(shè)計(jì)模式。
單例模式定義:確保某個(gè)類只有一個(gè)實(shí)例,而且自行能夠?qū)嵗⑾蛘麄€(gè)系統(tǒng)提供這個(gè)實(shí)例。
可以被設(shè)計(jì)單例模式的對(duì)象:線程池、緩存、日志對(duì)象、對(duì)話框、打印機(jī)、顯卡的驅(qū)動(dòng)程序等或多或少具有資源管理器的功能的對(duì)象
單例的特點(diǎn):
單例類只有一個(gè)實(shí)例;單例類必須自己創(chuàng)建自己的唯一實(shí)例;單例類必須給所有其他對(duì)象提供這一實(shí)例;
單例的模式:餓漢模式;懶漢模式;雙重檢查模式;靜態(tài)內(nèi)部類單例模式;使用容器實(shí)現(xiàn)單例模式
1:餓漢模式:
代碼如下:
public class Singleton {
private static Singleton instance = new? Singleton();
private Singleton(){
}
public static? Singleton getInstance(){
return instance;
}
}
?
PS:此種單例方法,在加載類的時(shí)候已完成實(shí)例化,因此會(huì)加載類的時(shí)間比較慢,調(diào)用此類調(diào)用類方法需要的時(shí)間較短,可避免多線程同步問題。
2:懶漢模式(線程不安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
?
PS:此方法實(shí)現(xiàn)了懶調(diào)用,節(jié)約了資源,但用戶第一次調(diào)用的時(shí)候需要實(shí)例化,反應(yīng)稍慢。在多線程無法正常使用。
3:懶漢模式(安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
?
PS:這種方法雖然實(shí)現(xiàn)了在多線程可以使用,但是每次調(diào)用getInstance方法時(shí)都需要進(jìn)行同步,造成不必要的同步開銷,而且大部分時(shí)候我們是用不到同步的,所以不建議用這種模式。
4. 雙重檢查模式 (DCL)
public class Singleton {
private volatile static Singleton instance = new? Singleton();
private Singleton(){}
public static? Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
PS:此方法在getSingleton方法中對(duì)singleton進(jìn)行了兩次判空,第一次是為了不必要的同步,第二次是在singleton等于null的情況下才創(chuàng)建實(shí)例。DCL優(yōu)點(diǎn)是資源利用率高,第一次執(zhí)行g(shù)etInstance時(shí)單例對(duì)象才被實(shí)例化,效率高。缺點(diǎn)是第一次加載時(shí)反應(yīng)稍慢一些,在高并發(fā)環(huán)境下也有一定的缺陷,雖然發(fā)生的概率很小。DCL雖然在一定程度解決了資源的消耗和多余的同步,線程安全等問題,但是他還是在某些情況會(huì)出現(xiàn)失效的問題,也就是DCL失效。
5. 靜態(tài)內(nèi)部類單例模式
public class Singleton {
private Singleton(){
}
public static? Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class? SingletonHolder{
private static final Singleton? sInstance=new? Singleton();
}
}
PS:第一次加載Singleton類時(shí)并不會(huì)初始化sInstance,只有第一次調(diào)用getInstance方法時(shí)虛擬機(jī)加載SingletonHolder 并初始化sInstance ,這樣不僅能確保線程安全也能保證Singleton類的唯一性,推薦使用此種單例模式。
6. 枚舉單例
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}??
PS:默認(rèn)枚舉實(shí)例的創(chuàng)建是線程安全的,并且在任何情況下都是單例
PS:杜絕單例對(duì)象被反序列化是重新生成對(duì)象代碼
private Object readResolve() throws ObjectStreamException{
return singleton;
}
7:使用容器實(shí)現(xiàn)單例模式
public class SingletonManager{private static MapobjMap=new HashMap();
private Singleton(){
}
private static void? registerService( String key,? Object instance){
if(!objMap.containsKey(key)){
objMap.put(key, instance) ;
}
}
public static? Object getService(String key){
return objMap.get(key);
}
}
PS:用SingletonManager 將多種的單例類統(tǒng)一管理,在使用時(shí)根據(jù)key獲取對(duì)象對(duì)應(yīng)類型的對(duì)象。這種方式使得我們可以管理多種類型的單例,并且在使用時(shí)可以通過統(tǒng)一的接口進(jìn)行獲取操作,降低了用戶的使用成本,也對(duì)用戶隱藏了具體實(shí)現(xiàn),降低了耦合度。
?
?
PS:好多好多,筆記先記在這里,后面續(xù)繼續(xù)理解記憶。