这更多是对概念问题的验证。我希望我不会在SO上违反可接受的问题规则。我尝试在答案线程上发表评论,但是SO不允许我这样做。
从这个问题的公认答案开始,这也是我曾经提出的问题-Non blocking locking,
可接受答案的选项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视为返回值。
因此,尽管“线程A恢复并看到inUseCount等于2”是可能的,但这不是代码执行的操作。它查看Increment()
的返回值,并且不依赖于任何挂起/恢复方案。