关于在c#中设置简单属性的非线程安全是什么?

bor*_*egg 5 c# multithreading thread-safety

我已经阅读了大量关于如何使属性线程安全的讨论和示例.这个线程安全包装类的页面上有一个

给出的例子是这样的:

internal class MyThreadSafeCass
{
    // *** Lock ***
    private object PropertyLock = new object();

    // *** Property ***
    private int m_Property = 0;

    // *** Thread-safe access to Property using locking ***
    internal int Property
    {
        get
        {
            lock (PropertyLock)
            {
                return m_Property;
            }
        }
        set
        {
            lock (PropertyLock)
            {
                m_Property = value;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

很清楚这里发生了什么,以及锁在做什么,但我很难理解它为什么需要它.为什么以下不是线程安全的?什么可能出错?

internal class MyThreadSafeCass
{
    // *** Property ***
    private int m_Property = 0;

    // *** Thread-safe access to Property using locking ***
    internal int Property
    {
        get
        {
            return m_Property;
        }
        set
        {
            m_Property = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

bor*_*egg 0

@Enigmativity 在这里获得了荣誉(不幸的是,如果不是要点的话),通过链接到这个关于跳过锁的博客,该博客又链接到这个关于 CPU 重新排序优化的博客,这是答案的真正核心。

总之,CPU 可以(并且确实)对涉及更改读/写执行顺序的代码进行优化。这些更改保证在它们执行的线程中是一致的并且不易察觉。但是,它们不(不能)保证访问共享内存的多个线程之间的一致性。正如最初问题中的示例所示,锁定对访问此共享内存施加了限制,从而恢复了一致性。

正如我所说,这是一个总结。我无法在上面链接的博客中的描述中添加任何内容,因此将推迟任何有兴趣了解完整答案的人点击这些链接。

@Enigmativity,如果您这样发布,我仍然会接受您的回答。否则,我会接受这个答案并关闭它。