非阻塞锁定-概念验证和后续行动

本文关键字:验证 锁定 | 更新日期: 2023-09-27 18:23:54

这更多的是对概念问题的验证。我希望我没有违反SO上的可接受问题规则。我试图评论回答线程,但SO不允许我这样做。

从这个问题的公认答案开始,这也是我的一个问题——非阻塞锁定,

可接受答案的选项2是:

private int _inUseCount;
public void MyMethod()
{
    if (Interlocked.Increment(ref _inUseCount) == 1)
    {
        // do some stuff    
    }
    Interlocked.Decrement(ref _inUseCount);
}

执行增量的线程似乎不一定是执行代码"//做一些事情"部分的线程

考虑这个场景:

  • ThreadA将_inUseCount增加到1并挂起
  • ThreadB将_inUseCount增加到2并挂起
  • ThreadA恢复并看到_inUseCount等于2,不执行代码的"做一些事情"部分,将_inUseCount减为1并完成
  • ThreadB恢复并看到_inUseCount为1,并执行代码的"做一些事情"部分

有没有办法使用这种范式来确保执行增量的线程就是执行代码的线程?

非阻塞锁定-概念验证和后续行动

执行增量的线程可能不一定是执行"//做一些事情"的线程

这是错误的。它们是一个代码路径的一部分,将在同一个线程上执行。

但只有当线程在启动时找到_inUseCount==0时,它才会执行"一些东西"。否则它将跳过该部分。


考虑这个场景:

  • ThreadA将_inUseCount增加到1并挂起
  • ThreadA恢复并看到_inUseCount等于2,不执行代码的"做一些事情"部分,递减_inUseCount至1并完成

ThreadA执行if (Interlocked.Increment(ref _inUseCount) == 1),这个线程将Interlocked.Increment()的契约视为其自己的Increment所做的返回值。

因此,尽管"ThreadA可能恢复并看到inUseCount等于2",但这不是代码所做的。它查看Increment()的返回值,这不依赖于任何挂起/恢复场景。