單例模式詳解

2021-09-10 04:52:20 字數 1818 閱讀 4983

單例模式在我們日常開發中,是我們最常見到的設計模式了。實現單例模式的方法有很多,有些人雖然會寫,但是對為什麼這麼寫,還是一點不明白。

下面我來給大家講講單例模式為什麼這麼寫,有什麼好處。

實現單例模式呢,一般有以下幾個關鍵點:

(1)私有的建構函式(無法通過new建立例項)

(2)通過靜態方法或者列舉提供物件的例項

(3)確保單例物件只有乙個(考慮多執行緒情況下)。

有時候在實現單例模式的時候,除了以上三點有時候我們還要防止反射破壞單例,反序列化的時候也會重新構建物件的例項。多程序的環境下,單例模式會失效,因為不同的程序執行在不同的虛擬機器中,記憶體是不一樣的。

下面我們來介紹常見的單例模式的寫法

上面這兩種都是餓漢式單例的寫法,為什麼說是餓漢式呢。因為上面兩種寫法,manager的例項,都是在manager這個類被初     始化的時候,就被建立好了。這種寫法,在多執行緒的環境下,也能保證只有乙個物件被建立。缺點呢就是如果不使用的話,就會白白建立這個單例物件。造成浪費。

上面這種單例模式,就是懶漢式的實現方法,我們可以看到在getinstance()方法上我們加上了 synchronized的關鍵字。

這樣我們就可以在多執行緒的環境下,也只會生成乙個物件的例項。但是上面這種寫法有個很明顯的缺點,就是我們的synchronized實現的是類鎖,在我們第一次初始化成功之後,以後每次通過getinstance()方法獲取物件的例項時,都要先獲取

當前類的類鎖,在執行完方法後,還要釋放鎖,造成了資源的不必要的浪費。synchronized操作是乙個重量的操作,我們應當盡量避免這種操作。下面我們在來介紹一種懶漢式單例的寫法 ,double check log 實現單例。

dcl實現的單例可以有效的避免我們上面的第一種懶漢式寫法所造成的每次呼叫getinstance()都要去獲取類鎖,執行完釋放鎖的操作。第一次初始化之後,我們呼叫該方法,發現物件已經例項化,直接返回當前已經例項化的物件。不會在走下面的同步操作。volatile關鍵字起到的作用是禁止指令重排序。避免多執行緒同時在獲取manger物件時,由於指令重排序,導致其他執行緒在獲取manger物件的時候,manger物件雖然不為null,但還沒有初始化。

靜態內部類實現單例的寫法,是我比較提倡的寫法了。第一在類初始化的時候,我們也不會去例項化物件,只有在呼叫getinsance()方法的時候我們才會去例項化物件,第二有效避免了加鎖造成的資源浪費,而且**更加簡潔。而且在多執行緒的環境下也能保證只有乙個例項。

寫法簡單是列舉單例的最大優點。而且列舉例項的建立時執行緒安全的。

還有就是以上的幾種單例寫法在反序列化的情況下會重新建立物件。而列舉不會。如果上述幾種寫法想避免在反序列的時候重新建立物件,那必須加入readresolve()方法。

單例模式詳解

單例模式的意思就是只有乙個例項。單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。1.單例模式的要點 顯然單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。2.單例模式的優點 1.例項控制 si...

單例模式詳解

單例模式是設計模式中比較常用的,今天我要詳細的了解一下,並且進行一些比較 public class singleton public static singleton getinstance catch interruptedexception e 單例模式的精髓就在這,類的內部可以new inst...

單例模式 詳解

保證乙個類僅有乙個例項,並且提供乙個訪問它的全域性訪問點 在該例項不存在的情況下,可以通過乙個方法建立乙個類來實現建立類的新例項 如果例項已經存在,它會簡單返回該物件的引用 建立型模式 var singleton function return var singlea singleton.getin...