围绕写的锁是否保证可以在另一个线程中重新读取? (.Net,内存模型)

假设我有一个属性,其设置程序受锁保护,但在吸气剂周围没有任何锁,例如

private long _myField;
public long MyProperty
{
    get { return _myField; }
    set { lock(whatever) _myField = value; }
}

除了同步写操作(而不是读操作)之外,锁(或更确切地说是Monitor.Exit)还应该导致volatile write.现在让我们说我们有两个线程A和B,并且发生以下顺序:

> A读取MyProperty的当前值.
> B将新值写入MyProperty.
> A再次读取MyProperty的当前值.

问:现在可以保证A看到新值吗?还是我们的锁只是确保B及时地写入主内存,而不确保其他线程读取新值?还是答案可能取决于我们是在.Net 2中运行还是在“更弱”的ECMA实现中运行?

解决方法:

不可以,因为读取没有显式的内存屏障,因此不能“保证”看到新的值.

您可以使用ReaderWriterLockSlim来确保a)写入相互锁定,b)读取始终获取新值.

private readonly ReaderWriterLockSlim _myFieldLock = new ReaderWriterLockSlim();
private long _myField;
public long MyProperty
{
    get 
    {
        _myFieldLock.EnterReadLock();
        try
        {
            return _myField;
        }
        finally
        {
            _myFieldLock.ExitReadLock();
        }
    }
    set
    {
        _myFieldLock.EnterWriteLock();
        try
        {
            _myField = value;
        }
        finally
        {
            _myFieldLock.ExitWriteLock();
        }
    }
}
上一篇:ActiveRecord“ Mysql :: Error:超出了锁定等待超时”,没有明显的锁定


下一篇:简单的线程问题,锁定对共享资源或整个功能的访问?