这种相互排斥的模式是否像我认为的那样安全?如果是这样,你怎么称呼它?
lock (_lock) {
if (_flag) return;
else _flag = true;
}
try {
//critical code...
}
finally {
_flag = false;
}
我想确保关键部分,但没有其他线程堆积等待获取锁定。显然,我确保标志设置在其他地方。还有更好的方法吗?
答案 0 :(得分:14)
不,那不安全。如果要确保互斥而不阻塞,可以使用Monitor.TryEnter:
if (Monitor.TryEnter(lockObj, 0)) {
// got the lock !
try {
// code
}
finally { // release the lock
Monitor.Exit(lockObj);
}
}
答案 1 :(得分:5)
你看过Monitor.TryEnter
吗?
答案 2 :(得分:3)
互斥模式的正确性取决于赋值_flag = false是原子的。想象一下如果分配可能被另一个线程中断会发生什么。如果通过测试将赋值的中间结果解释为false,则一个赋值可能导致多个线程进入临界区。
互斥模式的正确性还取决于编译器中是否缺少可能重新排列语句顺序的优化。想象一个“智能”编译器会将赋值_flag = false向上移动,因为_flag在其间的代码中没有被引用(并且其间的代码不会抛出异常)。然后,编译器可以优化锁定部分中的部分以读取
if(_flag) return;
模式可能失败的两个例子都是高度推测性的,我认为你可以安全地假设它有效。但是,如果存在另一个按要求运行的选项,那么最好使用它(参见其他帖子)。如果在同一代码中有其他开发人员,他们不需要考虑该模式是否有效。
答案 3 :(得分:0)
简单的lock(Object)
声明不会有效吗?在幕后,它会在Monitor
块内创建try... finally
和关键部分。
private static readonly Object lockMe = new Object();
lock(lockMe)
{
// critical code
}