下面的代码是我想要完成的一个非常简单的例子。
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设置为更高的风险,并且在这种情况下,_highestValue将是不准确的。
我知道我可以摆脱锁外的if语句,但我不想不必要地锁定。
有没有更好的方法来实现这一目标?可能是锁定和/或使用Interlocked命名空间的某种组合?
在某种程度上相关的说明,_highestValue应该是不稳定的吗?即便如此,我认为这对我手边的问题没有帮助。
谢谢!
答案 0 :(得分:2)
您所描述的是test and test and set的情况,是处理事物的一种非常有效的方式。要回答你的问题,如果没有在函数中封装条件,就无法摆脱代码重复。
答案 1 :(得分: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;
}