java設計模式之單例模式

2021-07-06 03:40:13 字數 2177 閱讀 3626

單例模式是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例類的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項而且該例項易於外界訪問,從而方便對例項個數的控制並提供全域性訪問點。

典型的**是:

public class singleton 

public static singleton getinstance()

return instance;

}}

但常常我們還要面對更複雜的現實問題。其他博主中也寫道單例分為懶漢和餓漢的模式。

有時我們會看到乙個singleton的成員變數全部是static型別的,這種情況下,建議直接刪除構造方法和靜態工廠方法,直接作為乙個工具類就好了。因為這個類已經不需要物件了,何必多此一舉呢?

構造方法不進行私有化,就意味著client可以自由的通過new singleton()構造新的例項,這已經有違了採用單例模式的本意,不如把靜態工廠方法刪掉吧,放棄單例的需求。如果有理由讓乙個類既可以是單例,也可以是多例,我想應該仔細設計了。

我們時常會看到這樣的構造方法:

public 

staticsingleton getinstance(context context)

如果乙個例項的構造需要引數,那麼就意味著傳遞不同的引數將影響到單例的狀態。比如我們看這樣一段**。

public class singleton 

public static singleton getinstance(object value)

return instance; }

public void fun()

}

在程式中的某處呼叫時使用了singleton.getinstance(obja).fun();另一處使用了singleton.getinstance(objb).fun();顯然,同樣乙個singleton例項,在執行時出現了未預期的行為。這與設計單例時我們期望的可控性是不符的,你無法預知在下一次使用value時真正的行為。

如果需要在繼承樹中使用單例,只要將基類的建構函式由private調整為protected即可,但問題會很多,這個有很多文章來討論了,在此略過。

簡而言之,如果在基類中實現靜態工廠方法,必然會與子類產生依賴,即發生父類依賴於子類的非正常情況。如果在子類中實現靜態工廠方法,則整個設計就出現了父類無法約束子類的建立情況,也就是說可能出現違背設計意圖的實現。建議對單例類不要再派生。

既然在軟體執行期內只有乙個例項,由於無法限制client的呼叫時機,就不可避免要處理互斥問題。

先來看靜態工廠方法的互斥處理,典型的**是:

public static singleton getinstance()

}} return instance;

}

這段**既完成了在構造這個唯一例項時的保護,又在構造完以後的多次獲取例項時不做無謂的互斥處理以提高執行效率,是目前比較推薦的實現方法。

再來看類的其他成員的互斥問題,這個就與其他class是一樣的了,需要小心的處理多執行緒訪問的影響。

2.6 在乙個程序中會同時出現多個單例嗎

在分布式系統、多個類載入器、以及序列化的的情況下,會產生多個單例,這一點是無庸置疑的。什麼情況下使用單例提供的getinstance()方法只能得到同乙個單例,除非是使用反射方式,將會得到新的單例。**如下

class c = class.forname(singleton.class.getname());

constructor ct = c.getdeclaredconstructor();

ct.setaccessible(true);

singleton singleton = (singleton)ct.newinstance();

這樣,每次執行都會產生新的單例物件。所以運用單例模式時,一定注意不要使用反射產生新的單例物件。

單例的記憶體問題也是值得關注的,一量單例建立以後,靜態變數instance就會持有乙份記憶體引用,而且由於其static性質,這份記憶體將在程式執行期間持續占用,無法通過gc進行**。所以對記憶體敏感的程式要減少對單例的使用,或者妥善處理記憶體**問題。

java設計模式之單例模式

單位面試題目中有一道關於單例模式的題目.大多數參加筆試的同事都會寫出getinstance這個函式,但是當我問起什麼情況下需要使用單例 單例具體有什麼好處的時候 static函式也可以構建唯一例項,為什麼還需要單例.從使用單例的經驗來看,如下場景下,個人感覺應該使用單例 1.如果需要構建乙個工具類,...

java設計模式 之 單例模式

單例模式 有些類在程式執行過程中只需要儲存乙個例項,比如檔案管理類,音訊管理類,那麼我們如何實現乙個單例類呢?有以下幾點 1 定義乙個靜態變數 2 建構函式私有化 3 提供乙個public 靜態方法,獲取這個例項 4 一定要做執行緒同步 public static class singleton p...

Java設計模式之單例模式

說到單例模式 大家一定非常熟悉 這是最常見也是設計模式中相對簡單 好理解的設計模式 今天就跟大家掰一掰單例模式 單例模式確保某個類只有乙個例項 應用場景 執行緒池 快取 等物件常常被設計成單例 然而單例分兩種 1 惡漢式 2 懶漢式 我們先來看下 惡漢式 public class singleton...