2

这更多是对概念问题的验证。我希望我没有违反关于 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 并执行代码的“做一些事情”部分

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

4

1 回答 1

4

执行增量的线程不一定是执行“//做一些事情”的线程

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

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


考虑这种情况:

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

ThreadA 执行if (Interlocked.Increment(ref _inUseCount) == 1),并且Interlocked.Increment()这个 Thread 将看到它自己的 Increment 所做的返回值。

因此,虽然"ThreadA resumes and see that inUseCount is equal to 2"是可能的,但这不是代码所做的。它查看 和 的返回值Increment(),它不依赖于任何挂起/恢复方案。

于 2013-07-18T07:07:49.997 回答