C# – Is a lock necessary in this situation

clockingmultithreading

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.

Best Answer

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).