Say I have a property whose setter is protected by a lock, but without any lock around the getter, e.g.
private long _myField;
public long MyProperty
{
get { return _myField; }
set { lock(whatever) _myField = value; }
}
In addition to synchronizing writes (but not reads), the lock, or rather Monitor.Exit, should cause a volatile write. Let’s now say we have two threads A and B, and the following sequence happens:
- A reads the current value of
MyProperty. - B writes a new value to
MyProperty. - A reads the current value of
MyPropertyagain.
Q: Is A now guaranteed to see the new value? Or did our lock just ensure that B writes to main memory in a timely manner, but not that other threads read a fresh value? Or could the answer even depend on whether we’re running in .Net 2+ or a “weaker” ECMA implementation?
No, since the read does not have the explicit memory barrier, it is not “guaranteed” to see the new value.
You can use a
ReaderWriterLockSlimto insure that a) the writes lock each other and b) the reads always pickup the new value.