Eri*_*ang 7 c# multithreading interlocked
如果许多线程同时调用GetNextNumber
以下代码,GetNextNumber
将比任何其他数字多返回 1 次。
private class RoundRobbinNumber
{
private int _maxNumbers = 10;
private int _lastNumber;
private RoundRobbinNumber(int maxNumbers)
{
_maxNumbers = maxNumbers;
}
public int GetNextNumber()
{
int nextNumber = Interlocked.Increment(ref _lastNumber);
if (_lastNumber > _maxNumbers)
{
Interlocked.CompareExchange(ref _lastNumber, 1, _maxNumbers);
nextNumber = 1;
}
return nextNumber;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以将返回值重置_lastNumber
为 1,并可靠地为每个调用的线程返回一个递增的数字GetNextNumber()
,而无需使用锁?
安德烈的回答没有条件陈述:
using System;
namespace Utils
{
public class RoundRobinCounter
{
private int _max;
private int _currentNumber = 0;
public RoundRobinCounter(int max)
{
_max = max;
}
public int GetNext()
{
uint nextNumber = unchecked((uint)System.Threading.Interlocked.Increment(ref _currentNumber));
int result = (int)(nextNumber % _max);
return result;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是运行此代码的.net fiddle 。
诀窍是循环执行该操作,直到成功。我在此处的回答中提供了此方法的通用模板。
public int GetNextNumber()
{
int initial, computed;
do
{
initial = _lastNumber;
computed = initial + 1;
computed = computed > _maxNumbers ? computed = 1 : computed;
}
while (Interlocked.CompareExchange(ref _lastNumber, computed, initial) != initial);
return computed;
}
Run Code Online (Sandbox Code Playgroud)