Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a lock necessary in this situation?

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.

like image 329
Tommy Carlier Avatar asked Jan 11 '10 16:01

Tommy Carlier


People also ask

Why are locks needed in a multi threaded program?

When you run a program with multithreading it is very hard to debug what happens when exactly and which thread has priority over other threads to access the shared resource. Here is where locks come into play and we use them to prevent those same deadlocks.

What is a lock multithreading?

A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can acquire the lock and everyone accesses to the shared resource requires that the lock be acquired first.


3 Answers

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

like image 116
Jon Skeet Avatar answered Oct 22 '22 05:10

Jon Skeet


There is the volatile keyword for this. Whether it's safe without it depends on the scenario. But the compiler can do funny stuff, such as reorganize order of operation. So even read/write to one field may be unsafe.

like image 42
ewernli Avatar answered Oct 22 '22 05:10

ewernli


It can be an issue. It's not just the assignment itself you have to be concerned with. Due to caching, concurrent threads might see an old version of the object if you don't lock. So whether a lock is necessary will depend on precisely how you use it, and you don't show that.

Here's a free, sample chapter of "Concurrent Programming in Windows" which explains this issue in detail.

like image 4
Craig Stuntz Avatar answered Oct 22 '22 07:10

Craig Stuntz