設計模式之單例模式 Singleton

2021-08-26 11:36:18 字數 1962 閱讀 3121

單例模式:確保乙個類只有乙個例項,並提供乙個全域性訪問點。

要想保證乙個類只有乙個例項,我們不能將構造方法暴露出去,否則呼叫方就可能通過你提供的構造方法去例項化該類的例項,這樣我們就無法保證該類只有乙個例項了。因此,我們不能給類的構造方法賦予public的訪問許可權。

單例模式的例項化分為兩種:急切例項化和延遲例項化

急切例項化:依賴jvm在載入這個類時馬上建立此唯一的單件例項,通常表現為乙個靜態引用。如果程式總是建立並使用單件例項,或者在建立和執行時方面的負擔不太繁重,我們可以採取急切例項化的方式建立單件。

public class product 

public static product newinstance()

}

急切例項化單例模式uml圖:

延遲例項化:只在真正需要該類的例項的時候才例項化。通常在建立和執行時負擔比較重的時候選用此種方案。

public class product 

public static product newinstance()

return product;

}}

延遲例項化單例模式uml圖:

延遲例項化所面臨的執行緒安全問題:

很多人在使用延遲例項化單例模式時都沒有考慮執行緒安全問題。我們看下面一段**:

/**

* 延遲例項化單例模式

*/public class product

public static product newinstance() throws throwable

return product;

}}

上段**有時也可能只會建立乙個例項,這取決哪個執行緒搶占到執行權,但不排除建立兩個例項的可能性,有興趣的朋友可以自己多嘗試幾次,或者借助除錯的手段手動切換兩個執行緒的執行順序,就會出現建立兩個例項的情景。既然如此,我們以後就不要像上面的**這樣使用延時例項化。

如何解決延遲例項化所面臨的執行緒安全問題:

方法一:使用synchronized,如下所示:

/**

* 延遲例項化單例模式

*/public class product

public static synchronized product newinstance() throws throwable

return product;

}}

上面的**雖然能解決執行緒安全問題,但是每次呼叫newinstance方法時都會被同步,無疑會帶來效能損耗,你必須知道同步乙個方法可能造成程式執行效率下降100倍。如果你可以接受這樣的額外損耗,你大可可以這樣來用(即簡單又有效),如果你可能需要頻繁的呼叫這個同步方法,又無法接受這樣的效能損失,可能就得想其他的辦法啦。

方法二:使用「雙重檢查加鎖」,如下所示:

/**

* 延遲例項化單例模式

*/public class product

public static product newinstance() throws throwable

}} return product;

}}

這樣做比直接使用同步方法帶來的損耗要低很多。如果你不想使用synchronized,也可以使用阻塞佇列,jdk也是這麼推薦的。

方法三:使用急切例項化,當然之前介紹了急切例項化也有他的缺點,如果你能接受的話,這也是個簡單有效的方案。

單例模式請注意多個classloder

每個類載入器都定義了乙個名空間,如果有兩個以上的類載入器,不同的類載入器可能會載入同乙個類,從整個程式來看,同乙個類被載入多次,如果這樣的事情發生在單件上,就會產生多個例項並存的「單件」,所以需要引起注意。

Java設計模式 單例模式(single)

目錄目的 應用例項 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。菜鳥教程 乙個國家有乙個首都 windows 是多程序多執行緒的,在操作乙個檔案的時候,就不可避免地出現多個程序或執行緒同時操作乙個檔案的現象,所以所有檔案的處理必須通過唯一的例項來進行。第一種 package com.ga...

設計模式之單例模式

前一段時間買了一本秦小波寫的 設計模式之禪 網上對這書的評價很高。現在還沒有看很多,但是有些地方頗有感觸,也並不是所有的地方都能看懂,但是會慢慢研究的。自己對於設計模式的感覺就是乙個字 牛!感覺會23種設計模式並且會熟練運用的人,真的就是大師級的牛人了,設計模式是乙個專案主管或者架構師一定要會的東西...

設計模式之單例模式

package com.xie.singleton public class singleton 提供乙個共有的靜態的入口方法 public static singleton getinstance 懶漢式 延遲載入 提供乙個私有的靜態的成員變數,但不做初始化 private static sing...