为什么Interlocked.CompareExchange无法正常工作?

if (Interlocked.CompareExchange(ref this.popcount, this.popcount + 1, this.popcount) == this.popcount)
{
    pop = Interlocked.CompareExchange(ref head, head.next, head);
}

我写了一个代码,但是某种程度上它并没有按我想要的那样工作...

Interlocked.CompareExchange(ref this.popcount, this.popcount + 1, this.popcount)

我认为这意味着

  1. go to this.popcount reference and get value of popcount
  2. compare value with this.popcount
  3. if it is same, add 1 to this.popcount

我错了吗?如果我错了,我该如何纠正?

评论
  • 也许
    也许 回复

    您需要记住添加1的值,即“ before”值,并且不能依赖(重新)从要更改的变量中读取该值。因为重点是多个线程竞争更新此变量的值。所以你想要像这样的东西:

    var oldcount = this.popcount;
    var newcount = oldcount + 1;
    
    if(Interlocked.CompareExchange(ref this.popcount, newcount, oldcount) == oldcount)
    {
        //It worked
    }
    else
    {
        //Loop round, try again, whatever you plan to do when you don't succeed.
    }
    

    With your example, even if the CompareExchange succeeds, you're then comparing the old value (returned by CompareExchange) to the new value (that you freshly read via this.popcount to the right of ==) and it's unlikely those will ever match.