假设我有一个属性,其设置程序受锁保护,但在吸气剂周围没有任何锁,例如
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();
}
}
}