23種設計模式之單例模式

2022-03-30 03:27:44 字數 2610 閱讀 4002

單例模式屬於建立型模式,保證在程式執行期間乙個類只有乙個例項,並提供乙個全域性訪問點

推薦訪問我的個人**,排版更好看呦:

什麼是單例模式

單例模式目的是保證在程式執行期間乙個類只有乙個例項,並提供乙個全域性訪問點,無論什麼情況下,只會生成乙個例項,免去繁瑣的建立銷毀物件的過程。

如何設計單例

如何設計單例模式其實很簡單,只需要考慮乙個問題,例項是否可以保證是全域性唯一,只要滿足這個條件,這個單例設計的肯定就合格了。

關於例項是否可以保證是全域性唯一的延伸出的問題:

是否執行緒安全,不安全肯定就不能保證全域性只有乙個例項

是否支援序列化,支援序列化的類,被反序列化之後肯定就不是全域性唯一了

是否支援反射,支援反射肯定也不是全域性唯一的

是否可以被轉殖,這個也不能保證全域性唯一

所以設計乙個安全的單例需要考慮的問題還是很多的。

針對上述問題常見的解決辦法:

保證執行緒安全,使用volatile+synchronized實現

防止序列化攻擊,重寫readresolve方法

防止反射,常用的方案是在單例類裡增加乙個boolean型別的flag標識,在例項化的時候先判斷flag標識

防止轉殖,重寫clone()方法

實現乙個最簡單的單例就需要考慮到以上的所有問題,這個時候什麼有用的方法還沒寫那,**就已經很多了,那有沒有簡單的辦法既滿足上述條件,**又簡潔那,那肯定有,使用列舉實現單例。

常見的單例模式設計方案

常見的單例模式設計方案大概有五種,懶漢模式,餓漢模式,雙重檢查方式實現,靜態內部類實現,列舉實現。

簡單的分個類:

是否支援延遲載入,分為懶漢模式和餓漢模式

執行緒安全設計了雙重檢查模式實現,靜態內部類實現方式

不支援序列化,反射,轉殖,列舉實現方式

其中懶漢模式,餓漢模式,雙重檢查方式實現,靜態內部類的實現方式都可以概括為以下兩步:

建構函式私有化,保證在外部無法new物件

提供乙個static方法獲取當前例項(不同方案,實現不同)

當然列舉的實現方式最簡單,也最安全的,所以推薦使用列舉實現,其次推薦使用靜態內部類方式實現。

餓漢模式

不是延遲載入,載入類的時候直接初始化

/**

* @auther: chenmingyu

* @date: 2019/2/12 16:26

* @description:

*/public class singleton

public static singleton getinstance()

}

優點:執行緒安全,**簡單。

缺點:不是延遲載入,如果你用不到這個類,它也會例項化,還有乙個問題就是如果這個例項依賴外部一些配置檔案,引數什麼的,在例項化之前就要獲取到,否則就例項化異常

懶漢模式

延遲載入,首次需要使用的時候在例項化,需要考慮執行緒安全

執行緒不安全的實現方式

public class singleton 

public static singleton getinstance()

return singleton;

}}

雙重檢查(dcl:double check lock)

執行緒安全的實現方式:

public class singleton 

public static singleton getinstance()}}

return singleton;

}}

面試官:為什麼使用volatile修飾singleton變數?

說的volatile,首先肯定回答volatile的可見性

防止重排序優化,如果不用volatile修飾,多執行緒的情況下,可能會出現執行緒a進入synchronized**塊,執行new singleton();,首先給singleton分配記憶體,但是還沒有初始化變數,這時候執行緒b進入getinstance方法,進行第乙個判斷,此時singleton已經不為空,直接返回singleton,然後肯定報錯。使用volatile修飾之後禁止jvm重排序優化,所以就不會出現上面的問題

靜態內部類實現

使用靜態內部類實現也是延遲載入,利用靜態內部類去實現執行緒安全,只有在第一次呼叫getinstance方法的時候才會去載入singletonholder,初始化singleton

public class singleton 

public static singleton getinstance()

private static class singletonholder

}

列舉實現

列舉實現**更簡潔,執行緒安全,並且保證列舉不會被反序列化,反射和轉殖

/**

* @auther: chenmingyu

* @date: 2019/2/12 16:30

* @description:

*/public enum singleton

}

所以推薦使用列舉方式,呼叫singleton.singleton.method();

23種設計模式之單例模式

我們也經常遇到類似的情況,為了節約系統資源,有時需要確保系統中某個類只有唯一乙個例項,當這個唯一例項建立成功之後,我們無法再建立乙個同型別的其他物件,所有的操作都只能基於這個唯一例項。為了確保物件的唯一性,我們可以通過單例模式來實現,這就是單例模式的動機所在。定義 單例模式 singleton pa...

23種設計模式之 單例模式

保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。讓類自身負責儲存它的唯一例項,這個類可以保證沒有其他例項可以被建立,並且它可以提供乙個訪問 獲取 該例項的方法。單例類應滿足以下特點 單例類 singleton 自己例項化自己的唯一例項,並提供訪問該唯一例項的方法。public class s...

23種設計模式之單例模式

單例模式 確保乙個類最多只有乙個例項,並提供乙個全域性訪問點 普通單例模式示例 有問題 public class singleton public static singleton getinstance return uniqueinstance 示例singleton public class ...