我应该如何增加循环线程场景中争用最少的数字?

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(),而无需使用锁?

Ale*_*tov 7

安德烈的回答没有条件陈述:

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 。


Bri*_*eon 5

诀窍是循环执行该操作,直到成功。我在此处的回答中提供了此方法的通用模板。

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)