Singleton Pattern 單態模式

2021-08-30 16:25:00 字數 1935 閱讀 6439

singleton pattern 單態模式。

這個模式較簡單,就是為了保證乙個類只有乙個例項,用乙個入口來獲取該例項。

例子如下(**來自維基):

class foo 

public static helper gethelper()

// other functions and members...

}

由於構造方法設為了私有,所以其它類無法使用new 來生成該類例項,只有通過

該類自己提供的方法來獲取例項。這個獲取例項的方法通總是使用第一次建立的

例項而保證其它類總是使用同乙個例項。

本來很簡單,但是在多執行緒情況下則會有些麻煩。兩個執行緒都有可能執行到了第

6行,這樣就有可能建立2個例項。過程如下(執行緒1簡稱為t1,執行緒2 簡稱t2):

t1 5 (5代表第5行)

t2 5

t1 6

t1 7 (執行緒1返回乙個例項)

t2 6

t2 7 (執行緒2返回另乙個例項)

這樣就破壞了例項唯一性。如果這兩個例項狀態不會變化,倒也無所謂,就是多

花點記憶體養兩個物件。但如果這兩個例項涉及到計數器等狀態變化,就埋下了隱患。

解決辦法是加上同步關鍵字,如下:

public static synchronized helper gethelper()

問題是解決了,但效率卻降低了。因為每次獲取例項都會執行同步運算。實際上

沒必要。一旦例項建立並返回,以後再獲取例項就不會執行第6行。為了發生機率

很小的事件而每次同步的方法,代價太大了。

不同虛擬機器對同步方法的執行效率不同,早期虛擬機器執行同步效率非常的低。現

在改進了很多,但進入執行緒體、離開執行緒體、加鎖、解鎖這些步驟仍然耗費效能。

所以,後來發明了雙檢查鎖模式。(double-checked locking pattern)。在

《designpattern***plained》一書中,作者專門分析了這種方法的優勢,並給出

了**。**如下:

class ustax ;

public static ustax getlnstance ()

}

不想,書上印錯了,這讓很多人包括我迷惑良久。後來書本經過更正,變為如下形式,

class ustax ;

public static synchronized void dosyn()//這句是我加的,為方便接下來的解釋。

}public static ustax getlnstance ()

}

到此,算是萬事大吉了。不料這種雙重檢查模式仍然有問題,並不能解決多執行緒

的問題。由於這本書的廣泛流傳,這種模式也廣為人知。當這種模式的錯誤之處

被發現後,很快就出現了對這種模式廣泛的討伐之聲。可見,影響越大,一旦有

錯,被討伐的力度也就越大。

我們以上面這段**為例,看看問題是怎樣產生的,

t1 10 (執行緒1執行到第10行)

t1 5

t1 6

t2 10

t2 12

也就是說,執行緒1還沒有完全構造完這個物件(還沒有執行第7行),執行緒2就返回

這個半成品物件了。所以,這種謬種流傳的 double-checked locking pattern也

就壽終正寢,不能再被使用了。

那這種多執行緒出現的問題該怎麼做呢,解決方法也很簡單,如下即可,

class ustax ;

public static synchronized void dosyn()

public static ustax getlnstance ()

}

5 Singleton Pattern 單例模式

單例模式主要符合單一職能原則。當乙個類的職責是一定的,而且整個程式中不需要生成第二個此類的物件,而且如果生成第二個此類的物件的話還會有問題 比如我之前寫的聯棋遊戲,裡面的棋盤就應該始終只有乙個物件,如果有兩個會造成混亂 為了防止生成兩個物件,而且節約記憶體,會使用單例模式。使用單例模式的典型場景比如...

單例模式(Singleton Pattern)

在 design patterns elements of resuable object oriented software 中的定義是 ensure a class only has one instance,and provide a global point of access to。它的主...

單例模式(Singleton Pattern)

單例模式確保乙個類只有乙個例項,並提供乙個全域性訪問點。某些物件我們只需要乙個,比如執行緒池 快取 登錄檔等等。如果這些類擁有多個例項,可能會產生很多問題。使用單例模式可以確保我們使用的這些全域性資源只有乙份。乙個經典的單例模式的實現 public class singleton public st...