導航:首頁 > 編程語言 > java線程安全單例

java線程安全單例

發布時間:2023-07-13 13:15:08

Ⅰ 單例模式的作用及創建方法

單例模式作為常見的設計模式之一,在java的項目開發中會時常的用到。Java Singleton模式即保證在JVM運行時,一個類Class只有一個實例存在。

單例模式有什麼好處呢?
最簡單的一個例子就是網站計數器的設計了。當我們想要統計當前網站的在線人數時,一個顯而易見的問題就是並發所帶來的線程安全問題,當我們對這個計數器(網站人數)在同一時刻進行操作,再保存計數時就會造成數據的混亂,後者覆蓋前者的結果。一種解決方案就是把這個計數器設置為唯一對象,所有人都必須共用同一份數據。
實現唯一對象最好的解決辦法就是讓類自己負責保存它的唯一實例,並且讓這個類保證不會產生第二個實例,同時提供一個讓外部對象訪問該實例的方法。自己的事情自己辦,而不是由別人代辦,這非常符合面向對象的封裝原則。

單例模式的三個特點:

只有在自身需要的時候才會行動,從來不知道及早做好准備。它在需要對象的時候,才判斷是否已有對象,如果沒有就立即創建一個對象,然後返回,如果已有對象就不再創建,立即返回。

該方法在多線程情況下有可能重復創建實例,以下是線程安全的懶漢模式

這種模式的缺點是加鎖造成了效率下降,並且在絕大部分情況下是不需要同步的。使用雙重檢驗鎖(DCL),只在第一次初始化的時候進行同步加鎖

該方式在類載入的時候就被實例化了。

這種方式同樣利用了classloder的機制來保證初始化instance時只有一個線程,它跟餓漢不同的是(很細微的差別):餓漢方式是只要Singleton類被裝載了,那麼instance就會被實例化(沒有達到lazy loading效果),而這種方式是Singleton類被裝載了,instance不一定被初始化。因為SingletonHolder類沒有被主動使用,只有顯式通過調用getInstance方法時,才會顯示裝載SingletonHolder類,從而實例化instance。

想像一下,如果實例化instance很消耗資源,我想讓它延遲載入,另外一方面,我不希望在Singleton類載入時就實例化,因為我不能確保Singleton類還可能在其他的地方被主動使用從而被載入,那麼這個時候實例化instance顯然是不合適的。這個時候,這種方式就顯得很合理。

關於類載入情況下單例模式,如果單例由不同的類裝載器裝入,那便有可能存在多個單例類的實例。假定不是遠端存取,例如一些servlet容器對每個servlet使用完全不同的類 裝載器,這樣的話如果有兩個servlet訪問一個單例類,它們就都會有各自的實例。修復的辦法是

Ⅱ Java單例模式餓漢式會有線程安全問題嗎

1、答案:不會有線程安全問題。

2、首先,一個類可以被使用必須經過 載入、連接和初始化
3、餓漢模式的對象創建是在初始化的時候創建的,初始化操作是jvm執行的(會給類變數賦初始值,執行靜態代碼塊等,類變數是用static修飾的變數),並且在我們看來一個類的初始化只會執行一次(jvm會控制),是不會有線程安全問題出現的
3、糾錯:不是「類一載入就實例化」,而是類先載入、連接(此步驟執行時間不固定,但是在初始化執行前必須執行結束)。初始化執行的時機是你new了一個對象,或者使用了反射機制,或者調用類的靜態變數和方法或者啟動有main方法的類

Ⅲ Java的單例模式是不是線程安全的

單例也不能保證100%線程安全的。解決方法就是創建實例方法中加入java關鍵字synchronized。
java語言的關鍵字synchronized,可用來給對象和方法或者代碼塊加鎖,當它鎖定一個方法或者一個代碼塊的時候,同一時刻最多隻有一個線程執行這段代碼。當兩個並發線程訪問同一個對象object中的這個加鎖同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。然而,當一個線程訪問object的一個加鎖代碼塊時,另一個線程仍然可以訪問該object中的非加鎖代碼塊。

Ⅳ 設計模式之單例模式

本文開始整個設計模式的系列學習,希望通過不斷的學習,可以對設計模式有整體的掌握,並在項目中根據實際的情況加以利用。

單例模式是指一個類僅允許創建其自身的一個實例,並提供對該實例的訪問許可權。它包含靜態變數,可以容納其自身的唯一和私有實例。它被應用於這種場景——用戶希望類的實例被約束為一個對象。在需要單個對象來協調整個系統時,它會很有幫助。

1、單例類只能有一個實例
2、單例類必須自己創建自己的唯一實例
3、單例類必須給其他所有對象提供這一實例

1.盡量使用懶載入
2.雙重檢索實現線程安全
3.構造方法為private
4.定義靜態的Singleton instance對象和getInstance()方法

單例模式至少有六種寫法。

作為一種重要的設計模式,單例模式的好處有:
1、控制資源的使用,通過線程同步來控制資源的並發訪問
2、控制實例的產生,以達到節約資源的目的
3、控制數據的共享,在不建立直接關聯的條件下,讓多個不相關的進程或線程之間實現通信

Singleton通過將構造方法限定為private避免了類在外部被實例化,在同一個虛擬機范圍內,Singleton的唯一實例只能通過getInstance()方法訪問。但其實通過Java反射機制是能夠實例化構造方法為private的類的,那基本上會使所有的Java單例實現失效。

雖然也是只有一個線程能夠執行,假如線程B先執行,線程B獲得鎖,線程B執行完之後,線程 A獲得鎖,但是此時沒有檢查singleton是否為空就直接執行了,所以還會出現兩個singleton實例的情況。

既然懶漢式是非線程安全的,那就要改進它。最直接的想法是,給getInstance方法加鎖不就好了,但是我們不需要給方法全部加鎖啊,只需要給方法的一部分加鎖就好了。基於這個考慮,引入了雙檢鎖(Double Check Lock,簡稱DCL)的寫法:

使用volatile 的原因:
對於JVM而言,它執行的是一個個Java指令。在Java指令中創建對象和賦值操作是分開進行的,也就是說instance = new Singleton();語句是分兩步執行的。但是JVM並不保證這兩個操作的先後順序,也就是說有可能JVM會為新的Singleton實例分配空間, 然後直接賦值給instance成員,然後再去初始化這個Singleton實例。這樣就使出錯成為了可能,我們仍然以A、B兩個線程為例:

載入一個類時,其內部類不會同時被載入。一個類被載入,當且僅當其某個靜態成員(靜態域、構造器、靜態方法等)被調用時發生。

枚舉類實現單例模式是 effective java 作者極力推薦的單例實現模式,因為枚舉類型是線程安全的,並且只會裝載一次,設計者充分的利用了枚舉的這個特性來實現單例模式,枚舉的寫法非常簡單,而且枚舉類型是所用單例實現中唯一一種不會被破壞的單例實現模式。因為枚舉類沒有構造方法,可以防止反序列化操作。

1、除枚舉方式外, 其他方法都會通過反射的方式破壞單例,反射是通過調用構造方法生成新的對象,所以如果我們想要阻止單例破壞,可以在構造方法中進行判斷,若已有實例, 則阻止生成新的實例,解決辦法如下:

2、如果單例類實現了序列化介面Serializable, 就可以通過反序列化破壞單例,所以我們可以不實現序列化介面,如果非得實現序列化介面,可以重寫反序列化方法readResolve(), 反序列化時直接返回相關單例對象。

Runtime是一個典型的例子,看下JDK API對於這個類的解釋"每個Java應用程序都有一個Runtime類實例,使應用程序能夠與其運行的環境相連接,可以通過getRuntime方法獲取當前運行時。應用程序不能創建自己的Runtime類實例。",這段話,有兩點很重要:

1、每個應用程序都有一個Runtime類實例
2、應用程序不能創建自己的Runtime類實例
只有一個、不能自己創建,是不是典型的單例模式?看一下,Runtime類的寫法:

為了節約系統資源,有時需要確保系統中某個類只有唯一一個實例,當這個唯一實例創建成功之後,我們無法再創建一個同類型的其他對象,所有的操作都只能基於這個唯一實例。為了確保對象的唯一性,我們可以通過單例模式來實現。

單例模式應用的場景一般發現在以下條件下:
(1)資源共享的情況下,避免由於資源操作時導致的性能或損耗等。如上述中的日誌文件,應用配置。
(2)控制資源的情況下,方便資源之間的互相通信。如線程池等。

關於單例模式的漫畫分析: https://mp.weixin.qq.com/s/f-sJIZHr7JUa31gKTllSFQ

單例模式的優缺點、注意事項、使用場景

閱讀全文

與java線程安全單例相關的資料

熱點內容
頭條app如何設置橫屏模式 瀏覽:357
clion怎麼使用終端編譯 瀏覽:766
伺服器地址部署到公網 瀏覽:492
新桑塔納安卓大屏導航怎麼拆 瀏覽:382
程序員送給女友的禮物 瀏覽:430
ftp命令行查看文件數量 瀏覽:496
linux查看設備的命令 瀏覽:827
pythongolang學哪個 瀏覽:349
金蝶加密鎖驅動下載 瀏覽:300
python編程基於自然語言處理庫 瀏覽:133
javaseruntime 瀏覽:902
cad如何將命令放在滑鼠旁邊 瀏覽:746
程序員對粉色 瀏覽:125
編譯器命令java 瀏覽:989
雲伺服器怎麼數據同步 瀏覽:685
c盤文件修復命令語 瀏覽:966
文件夾中文件怎麼上下移動 瀏覽:831
魅族手機用什麼軟體解壓 瀏覽:763
加密幣糖果 瀏覽:300
c編譯調試是什麼 瀏覽:631