所以这是我的双重检查锁定的自定义实用程序:它是一个静态方法,您可以在其中提供标准,同步对象和要执行的操作。
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
在我的小世界中,如果可能出现这样的故障,那么还应该可以设计一个测试,通过足够多的并行测试用例来充分地使用场景来证明失败。我一直在寻找这样的测试大约一年,但到目前为止,我已经画了一个空白。谁能告诉我一个测试:
显示在没有内存屏障的情况下此方法失败;
显示在重复测试并恢复内存屏障时成功了吗?
答案 0 :(得分:1)
不,不可能测试非确定性行为(或者至少,如果你这样做,那么否定结果仍然是不确定的)。
答案 1 :(得分:0)
不可能构造这样的测试,因为“lock”语句已经为锁定的指令块创建了一个完整的栅栏(即获取和释放栅栏)。因此,额外的Thread.MemoryBarrier()
是多余的,没有任何效果。
因此,根据传递的委托criterion
的作用,您的RunIf
构造本身是安全的或完全是多余的。
我的意思是,如果传入的criterion
委托从可变状态派生其返回值,并且这个可变状态不受同一syncObject
的保护(直接或间接) ,此代码不安全,RunIf
基本上没有任何效果,除了围绕第二次调用criterion
代表完成围栏时执行的指令。