1

下面的代码是我想要完成的一个非常简化的示例。

 private object _highestLevelLock = new object();
    private int _highestValue;
    private void SetHighestValue()
    {
        var random = new Random();
        var next = random.Next(0, 100);
        if (next > _highestValue)
        {
            lock (_highestLevelLock)
            {
                if(next > _highestValue)
                    _highestValue = next;
            }
        }
    }

即,我有一个变量,它保存了迄今为止我遇到的最高整数。SetHighestValue() 可以被多个线程访问。

如果生成的随机整数大于当前最大的整数,我会更新_highestValue。

我的问题是,如果下一个 > 最高值,我怎样才能避免检查两次?如果我将其从锁内移除,那么在此线程设置值之前,_highestValue 可能会被设置为更高的值,在这种情况下,_highestValue 将不准确。

我知道我可以摆脱锁外的 if 语句,但我不想不必要地锁定。

有没有更好的方法来实现这一点?可能是锁定和/或使用 Interlocked 命名空间的某种组合?

在一些相关的说明中,_highestValue 是否应该是易变的?即使是这样,我认为这对我手头的问题没有帮助。

谢谢!

4

2 回答 2

2

您所描述的是一个测试、测试和设置的案例,是一种非常有效的处理方式。要回答您的问题,如果没有将您的条件封装在一个函数中,就无法摆脱代码重复。

于 2012-10-01T22:47:09.410 回答
1

我认为您可以使用Interlocked该类而不是锁定:具有较高值的​​每个线程都尝试执行更新,但如果失败则重新检查:

var next = random.Next(0, 100);
int current = _highestValue;
bool updated = false;
while(next > current && !updated)
{
    updated = Interlocked.Exchange(ref _highestValue, next, current);
    current = _highestValue;
}
于 2012-10-01T22:50:46.380 回答