2016-08-03 64 views
-1

C#我移植了一些遺留代碼,發現一些類有如下鎖定對象:鎖定在使用Environment.TickCount

protected readonly object _stateLock = Environment.TickCount; 

沒有任何優勢,這在新的對象()? 傳來傳去另一個鎖定對象我看到的是

private Nullable<int> _sLock = new Nullable<int>(Environment.TickCount); 

任何優勢,使用這個?

+1

我無法想象鎖定盒裝int的任何優勢。誰寫的可能只是忽略了創建鎖對象的簡單方法,一個簡單的'new object()'。 –

+1

第二個片段的唯一優點是你永遠不會遇到死鎖。 * lock *語句必須包含它並始終生成一個唯一對象。當然,你永遠不會得到工作鎖。這位程序員不知道他在做什麼。 –

回答

4

不,沒有任何優勢。 Environment.TickCountNullable<int>值都是值類型,並將被裝箱,即包裝在新的object參考中。

代碼的第二個版本實際上更糟糕。第一個,使用TickCount,僅僅是分配新的object參考的低效方法。但引用永遠不會改變,否則鎖定會正常工作。 lock聲明(或更確切地說,底層的Monitor類)完全不關心對象內的值是什麼;它所關心的只是參考本身。所以拳擊TickCount17或只是創建一個新的object,都是一樣的。

第二個版本,其中使用Nullable<int>只是明顯錯誤,並且根本不會實現鎖定行爲。因爲Nullable<int>本身就是一個值類型,所以當任何代碼試圖鎖定該值時(即lock (_sLock)),該值將在該時間點被裝箱,爲該鎖創建一個全新的object引用。只有在每個需要共享數據的代碼的關鍵部分也使用相同的object參考進行鎖定時,鎖才起作用。由於他們都將獲得自己的新參考,所以根本不會發生同步。

我還應該指出,編譯器通常不會允許您執行第二個版本。即如果你試圖編譯這段代碼,它會失敗與錯誤:

Nullable<int> _sLock; 

lock (_sLock) { } 

錯誤會讀

error CS0185: 'int?' is not a reference type as required by the lock statement

如果你確實有像你說的代碼的地方寫的,那麼是誰寫它的人繞過這個非常有用的編譯器錯誤,通過強制執行_sLock值,例如是這樣的:

lock ((object)_sLock) { } 

如果我看到這樣的代碼,我會立即懷疑是誰寫它的人的能力,並會堅持審查他們感動的應該是線程安全的任何代碼,看什麼否則他們搞砸了。