2010-04-08 65 views
7

正如我知道,有兩種常見的做法,以確保懶初始化的線程安全:在Delphi中實現雙重檢查鎖定是否可能或合理?

  1. 雙檢鎖(標記變量爲揮發性避免記憶排序)
  2. InterlockedCompareExchangePointer

看來VCL使用第二種做法。有什麼理由嗎?

class function TEncoding.GetUTF8: TEncoding; 
var 
    LEncoding: TEncoding; 
begin 
    if FUTF8Encoding = nil then 
    begin 
    LEncoding := TUTF8Encoding.Create; 
    if InterlockedCompareExchangePointer(Pointer(FUTF8Encoding), LEncoding, nil) <> nil then 
     LEncoding.Free; 
    end; 
    Result := FUTF8Encoding; 
end; 

還是有沒有更好的方法?

謝謝!

回答

4

應該沒有太大的速度差異。在兩種方法中,首先檢查全局字段是否已初始化,並僅在需要時才執行初始化。因此,大多數情況下,函數只會進行比較,跳轉,移動,而不需要任何初始化。

執行初始化時,InterlockedCompareEtc與鎖定相比具有兩個優點。

  1. 它更快。
  2. 代碼更短(不需要初始化鎖等)。

我發現InterlockedCompareEtc方法「整潔」,並在我的代碼中使用它。但鎖定功能同樣適用。

+0

我不喜歡代碼重複,所以我得到一些想法,可以簡化上述代碼: 1.當PARAM類型「T」具有默認構造 結果:= TUtils.GetInstance (FUTF8Encoding,TUTF8Encoding); 2.使用匿名方法創建本地實例。 結果:= TUtils.GetInstance (FUTF8Encoding, function:TEncoding begin Result:= TUTF8Encoding.Create; end); 那怎麼樣? – 2010-04-14 04:07:38

+0

您應該編輯您的原始帖子,保羅,而不是寫評論。 – gabr 2010-04-14 06:16:58

相關問題