是否可以创建一个测试,显示C#中双重检查锁定的失败?

时间:2013-06-15 19:33:40

标签: c# multithreading locking

所以这是我的双重检查锁定的自定义实用程序:它是一个静态方法,您可以在其中提供标准,同步对象和要执行的操作。

public static bool RunIf(Func<bool> criterion, object syncObject, Action action)
{
    if (criterion())
        lock(syncObject)
            if (criterion())
            {
                Thread.MemoryBarrier(); 
                action();
                return true;
            }
    return false;
}

我了解到,根据C#规范,优化器可以以这样的方式重新排序内存分配:在没有内存障碍的情况下,这种技术可以给出误报并在应该执行时执行操作“T

在我的小世界中,如果可能出现这样的故障,那么还应该可以设计一个测试,通过足够多的并行测试用例来充分地使用场景来证明失败。我一直在寻找这样的测试大约一年,但到目前为止,我已经画了一个空白。谁能告诉我一个测试:

  1. 显示在没有内存屏障的情况下此方法失败;

  2. 显示在重复测试并恢复内存屏障时成功了吗?

2 个答案:

答案 0 :(得分:1)

不,不可能测试非确定性行为(或者至少,如果你这样做,那么否定结果仍然是不确定的)。

答案 1 :(得分:0)

不可能构造这样的测试,因为“lock”语句已经为锁定的指令块创建了一个完整的栅栏(即获取和释放栅栏)。因此,额外的Thread.MemoryBarrier()是多余的,没有任何效果。

因此,根据传递的委托criterion的作用,您的RunIf构造本身是安全的或完全是多余的。

我的意思是,如果传入的criterion委托从可变状态派生其返回值,并且这个可变状态不受同一syncObject的保护(直接或间接) ,此代码不安全,RunIf基本上没有任何效果,除了围绕第二次调用criterion代表完成围栏时执行的指令。