Использование блокировки - PullRequest
4 голосов
/ 09 февраля 2010

Является ли этот код потокобезопасным? или так:

Есть ли в любом случае вызов 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() или заблокировать все это в одном блоке?

1 Ответ

10 голосов
/ 09 февраля 2010

Да, есть возможность:

  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
...