Is it necessary to protect access to a single variable of a reference type in a multi-threaded application? I currently lock that variable like this:
private readonly object _lock = new object();
private MyType _value;
public MyType Value
{
get { lock (_lock) return _value; }
set { lock (_lock) _value = value; }
}
But I’m wondering if this is really necessary? Isn’t assignment of a value to a field atomic? Can anything go wrong if I don’t lock in this case?
P.S.: MyType is an immutable class: all the fields are set in the constructor and don’t change. To change something, a new instance is created and assigned to the variable above.
Being atomic is rarely enough.
I generally want to get the latest value for a variable, rather than potentially see a stale one – so some sort of memory barrier is required, both for reading and writing. A lock is a simple way to get this right, at the cost of potentially losing some performance due to contention.
I used to believe that making the variable volatile would be enough in this situation. I’m no longer convinced this is the case. Basically I now try to avoid writing lock-free code when shared data is involved, unless I’m able to use building blocks written by people who really understand these things (e.g. Joe Duffy).