Parallel.For不正确处理锁定

Bru*_*oLM 3 c# multithreading thread-safety

我做了以下测试:

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++;
    //}
});
Run Code Online (Sandbox Code Playgroud)

这将Parallel.For调用从0到19999传递值的方法.因此它将执行20k次.

如果我不换ThreadStaticVar++;lock,即使它有一个锁的getset,结果不会是20000.如果我删除注释栏并将其锁定在其中,.For则获取正确的值.

我的问题是:它是如何工作的?锁定为什么get并且set不起作用?为什么它只能在我的内部工作For

tza*_*man 5

++操作不是一个原子增量.将会有一个调用,get然后调用set,并且这些调用可以在不同的线程之间交错,因为锁定仅在每个单独的操作上.可以这样想:

lock {tmp = var}
lock {var = tmp+1}
Run Code Online (Sandbox Code Playgroud)

那些锁现在看起来不那么有效,是吗?