Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Interlocked

Is this code thread-safe? or put it this way:

Is there anyway to call GetIt() and that GetIt() will return the same number to 2 different threads

Private Shared hitCount As Long = 1

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

It seems like it's possible, then am I supposed to use Interlocked.Read() or lock the whole thing in one block?

like image 400
dr. evil Avatar asked Dec 29 '22 02:12

dr. evil


1 Answers

Yes there is a possibility:

  1. Thread 1 runs Threading.Interlocked.Increment(hitCount)
  2. Thread 2 runs Threading.Interlocked.Increment(hitCount)
  3. Thread 1 runs Return hitCount
  4. Thread 2 runs Return hitCount

In steps 3 and 4, hitCount will be the same value.

But the fix is easy Interlocked.Increment returns the incremented value, so just change your code to:

Private Shared hitCount As Long = 1L

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

Edit Or now based on your edit, you have a pretty bit timing hole. Anyway then this is what you want:

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

Edit Then do this (which is exactly what Michael suggested below)

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
like image 177
shf301 Avatar answered Jan 15 '23 22:01

shf301