对于竞争最少的循环线程方案,我应该如何增加数字? [英] How should I increment a number for a round robin threading scenario with least contention?

查看:49
本文介绍了对于竞争最少的循环线程方案,我应该如何增加数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果许多线程与以下代码同时调用 GetNextNumber ,则 GetNextNumber 返回的次数将比其他任何数字多1.

If many threads are calling GetNextNumber simultaneously with the following code, GetNextNumber will return 1 more times than any other numbers.

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;
    }
}

有没有一种方法可以将 _lastNumber 重置为一个,并为调用 GetNextNumber()的每个线程可靠地返回递增的数字,而不必使用锁?

Is there a way to reset the _lastNumber back to one, and reliably return an incremented number for each thread calling GetNextNumber(), without having to use a lock?

推荐答案

诀窍是循环执行操作,直到操作成功为止.我在此处的答案中为此方法提供了一个通用模板.

The trick is to do the operation in a loop until it is successful. I provide a general template for this approach in my answer here.

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;
}

这篇关于对于竞争最少的循环线程方案,我应该如何增加数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆