無鎖,執行緒安全,延遲載入的單例實現(C )

2021-09-08 16:59:19 字數 1328 閱讀 4374

單例(singleton)是非常常見,也非常有用的設計模式,當然了, 面試中也是經常會被問到的:)在幾乎所有的專案中都能看到它的身影。簡而言之,單例保證了乙個自定義型別在整個程式的生命週期只被建立一次。要實現乙個簡單的單例是也很容易的:

public class example

public static example instance

return instance;}}

}

這是大多數人的寫法。

這是乙個延遲載入的單例。換句話說,只有當呼叫example.instance時,才會建立example的例項。當不存在多執行緒呼叫的情況下,這個單例是工作得很好的。但是在現實中,我們已經很少不去考慮執行緒安全了。提到執行緒安全,我們第一反應就是加鎖:

public class example

public static example instance

return instance;}}

}}

這顯然是沒有問題的,我相信也是大多數程式設計師的做法。

在面試中如果面試者能夠在沒有任何提示下給出這個執行緒安全且延遲載入的單例,已經很讓面試官滿意了。 可是我想再吹毛求疵下:能不能實現乙個無鎖的執行緒安全單例?

無鎖且要執行緒安全。。。我們需要借助語言的特性。(實際上**更少了)

public class example

public static example instance

}}

的確,無鎖且執行緒安全了,但是。。。延遲載入似乎又缺失了。也許有人要問,這個延遲載入有什麼用?

絕大多數情況下,這個延遲載入沒有任何用(面試虐人除外),除非這個類還有其他static public methods。譬如說這個example類有乙個靜態方法:

public static string output()

並且我們只會用到example.output()。在這種情況下如果 example 的instance被建立了,顯然是浪費記憶體。據我所知,這是延遲載入唯一有用的地方。

不管這個延遲載入用處有多大,我們單純從研究的角度考慮,是否能既做到無鎖,執行緒安全,又延遲載入?

c#語言的另一大特性幫助了我們:巢狀類。直接上**:

public class example

public static example instance

}class nested

internal static readonly example instance = new example();

}}

如何實現無鎖的執行緒安全延遲載入單例?

單例是較為常見的設計模式,在實現延遲載入時,會出現執行緒安全的問題,我們一般採用加鎖的方式,不採用加顯式鎖的方式例如列舉 以及非延遲載入的方式之類的最終虛擬機器在執行的時候會幫我們加鎖。這個其實很好理解,我們可以看下如下的 class sim public static sim getinstanc...

既執行緒安全又支援延遲載入的單例模式

當 jvm 載入 lazyloadedsingleton 類時,由於該類沒有 static 屬性,所以載入完成後便即可返回。只有第一次呼叫 getinstance 方法時,jvm 才會載入 lazyholder 類,由於它包含乙個 static 屬性 singletoninstatnce,所以會首先...

java實現多執行緒延遲載入的單例模式

package offer 靜態變數,靜態方法,靜態塊等都是類級別的屬性,而不是單純的物件屬性。他們在類第一次被使用時被載入 記住,是一次使用,不一定是例項化 我們可以簡單得用 類名.變數 或者 類名.方法來使用它們。靜態內部類的載入不需要依附外部類,在使用時才載入所以當外部類載入的時候不會載入內部...