2010-02-09 49 views
4

此代碼是否線程安全?或者這樣說:使用聯鎖

反正是有來電GETIT()和GETIT()將相同數量恢復到2個不同的線程

Private Shared hitCount As Long = 1 

Public Shared Function GetIt() As Long 
    Threading.Interlocked.Increment(hitCount) 
    DoSomethingQuick(hitCount) 
    Return hitCount 
End Function 

看起來這是可能的,那麼我是應該使用Interlocked.Read()還是將所有內容鎖定在一個區塊中?

+0

我想你會打一個溢出異常,一旦你達到'Integer.MaxValue'? 'hitCount'是一個Long,但你返回一個Integer。 – 2010-02-09 17:09:10

+0

哈哈,修正了代碼。 – 2010-02-09 17:11:06

回答

10

是存在這樣的可能性:

  1. 線索1組的運行Threading.Interlocked.Increment(hitCount)
  2. 線程2個運行Threading.Interlocked.Increment(hitCount)
  3. 線索1組的運行Return hitCount
  4. 線程2個運行Return hitCount

在步驟3和4,hitCount將是相同的值。

但修復容易Interlocked.Increment返回增加後的值,所以只要改變你的代碼:

Private Shared hitCount As Long = 1L 

Public Shared Function GetIt() As Long 
    Return Threading.Interlocked.Increment(hitCount) 
End Function 

編輯 還是現在根據您的修改,你有一個漂亮的位定時孔。反正那麼這就是你想要的東西:

Public Shared Function GetIt() As Long 
    Dim localHitCount As Long = Threading.Interlocked.Increment(hitCount) 
    Console.Writeline("Something, something....") 
    Return localHitCount 
End Function 

編輯 那麼做到這一點(這正是邁克爾以下建議)

Private Shared hitCount As Long = 1L 

Public Shared Function GetIt() As Long 
    Dim localHitCount As Long = Threading.Interlocked.Increment(hitCount) 
    DoSomethingQuick(localHitCount) 
    Return localHitCount 
End Function 
+0

:)我不知道它是返回最後的值,不錯。 – 2010-02-09 17:23:51

+0

剛剛更新了代碼,使我的原始代碼相同(對不起,我嚴重寫了示例代碼)。 AFAIK在這個更新的代碼中,我必須用鎖來包裝整個東西。 – 2010-02-09 17:24:30

+0

您可以緩存來自Interlocked.Increment的返回值,並在調用DoSomethingQuick和返回時使用該值。 – Michael 2010-02-09 17:26:50