作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我做了以下测试:
private static object threadLocker = new object();
private static long threadStaticVar;
public static long ThreadStaticVar
{
get
{
lock (threadLocker)
{
return threadStaticVar;
}
}
set
{
lock (threadLocker)
{
threadStaticVar = value;
}
}
}
Parallel.For(0, 20000, (x) =>
{
//lock (threadLocker) // works with this lock
//{
ThreadStaticVar++;
//}
});
这个 Parallel.For
调用方法传递从 0 到 19999 的值。所以它会执行 20k 次。
如果我不使用 lock
包装 ThreadStaticVar++;
,即使它在其 get
和 set 上有锁
,结果不会是20000
。如果我删除注释栏并将其锁定在 .For
中,它会获得正确的值。
我的问题是:它是如何工作的?为什么 get
和 set
上的锁不起作用?为什么它只在我的 For
中有效?
最佳答案
++
运算符不是原子增量。将调用 get
,然后调用 set
,这些调用可以在不同线程之间交错进行,因为锁定仅针对每个单独的操作。可以这样想:
lock {tmp = var}
lock {var = tmp+1}
那些锁现在看起来不那么有效了,是吗?
关于c# - Parallel.For 没有正确处理锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9338358/
我是一名优秀的程序员,十分优秀!