單例模式 懶漢式 執行緒不安全詳解,以及如何解決?

2021-10-10 02:15:27 字數 2317 閱讀 8710

package singleton.demo;

/*懶漢式-單例模式*/

public

class

singletontwo

/*定義乙個私有的靜態成員屬性將該物件的引用指向null*/

private

static singletontwo instance = null;

/*提供乙個獲取該類物件的共有靜態方法,第一次呼叫該方法的時候會建立該類的例項物件並且將其儲存在靜態成員屬性中*/

public

static singletontwo getinstance()

throws interruptedexception

return instance;

}}

我們知道懶漢式的單例模式,建立物件的時機在第一次呼叫getinstance()方法。而安全隱患就存在這時間段,倘若有兩條執行緒都是執行該**段,一條執行緒執行過程進入了if語句塊且還沒有把建立物件的例項賦值給成員變數時恰好進入了阻塞狀態(還不清楚執行緒生命週期的小夥伴可理解為該執行緒暫停了)。由於if語句判斷條件依據是:instance == null才能進入該語句塊。那麼另一條執行緒就有可能會混進在該if語句塊,最後就會導致兩個執行緒建立了兩個不一樣的物件。

導致【單例模式-懶漢式】返回不同物件的「劇本」已經寫好了,上**:

微改一下實現單例的類:

在剛進入語句塊時呼叫thread.sleep(3000)讓該執行緒休眠三秒鐘。

package singleton.demo;

/*懶漢式-單例模式*/

public

class

singletontwo

/*定義乙個私有的靜態成員屬性將該物件的引用指向null*/

private

static singletontwo instance = null;

/*提供乙個獲取該類物件的共有靜態方法,第一次呼叫該方法的時候會建立該類的例項物件並且將其儲存在靜態成員屬性中*/

public

static singletontwo getinstance()

throws interruptedexception

return instance;

}}

package singleton.test;

import singleton.demo.singletontwo;

public

class

threadtest

implements

runnable

@override

public

void

run(

)catch

(interruptedexception e)

}}

由於執行緒執行是不確定的,因此有時候得嘗試多遍後才會出現返回不同物件的執行結果:

返回相同物件的執行結果:

返回不同物件的執行結果:

接下來我們可以使用synchronized 修飾符去修飾getinstance()方法。

package singleton.demo;

/*懶漢式-單例模式*/

public

class

singletontwo

/*定義乙個私有的靜態成員屬性將該物件的引用指向null*/

private

static singletontwo instance = null;

/*提供乙個獲取該類物件的共有靜態方法,第一次呼叫該方法的時候會建立該類的例項物件並且將其儲存在靜態成員屬性中*/

synchronized

public

static singletontwo getinstance()

throws interruptedexception

return instance;

}}

這樣就可以保證多執行緒下,依然能夠完整的執行getinstance(),即使休眠,其他執行緒也得等我睡醒。hhh。

以上這種方式叫做「同步鎖」即使用synchronized關鍵字實現執行緒的鎖定。當然還有其他方法可以達到這種效果。比如說:雙重校驗鎖,靜態內部類,列舉來去保證操作時的執行緒唯一。

設計模式之單例模式(執行緒安全和執行緒不安全的)

1 單例模式 確保某乙個類只有乙個例項物件,並提供乙個全域性的訪問點。特點 1 只有乙個例項 2 自我例項化 3 提供全域性訪問點 優點 節約系統資源,提高系統效率,同時也能控制客戶對他的訪問,但是擴充套件起來比較困難。例項 1 餓漢模式 public class student 2 懶漢模式 pu...

執行緒安全的懶漢式單例設計模式

首先回顧一下單利設計模式 單利設計模式是通過某種方式使某個類只能建立乙個物件例項供外界使用。單利設計模式分為懶漢式和餓漢式 餓漢式是執行緒安全的 1 餓漢式單利設計模式 2class single 5public static single getinstance 8 餓漢式實現執行緒安全,可以通過...

單例,包括懶漢式執行緒安全

package danli public class test1 class singleinstance private static singleinstance single null public static singleinstance getinstance return single...