Is a reference assignment threadsafe?

Steffen picture Steffen · Mar 6, 2011 · Viewed 11.6k times · Source

I'm building a multi threaded cache in C#, which will hold a list of Car objects:

public static IList<Car> Cars {get; private set;}

I'm wondering if it's safe to change the reference in a thread without locking ?

e.g.

private static void Loop()
{
  while (true)
  {
    Cars = GetFreshListFromServer();
    Thread.Sleep(SomeInterval);
  }
}

Basically it comes down to whether assigning a new reference to Cars is atomic or not I'd guess.

If it's not I'll obviously have to use a private field for my cars, and lock around getting and settings.

Answer

Marc Gravell picture Marc Gravell · Mar 6, 2011

Yes, reference updates are guaranteed to be atomic in the language spec.

5.5 Atomicity of variable references

Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic.

However inside a tight loop you might get bitten by register caching. Unlikely in this case unless your method-call is inlined (which might happen). Personally I'd add the lock to make it simple and predictable, but volatile can help here too. And note that full thread-safety is more than just atomicity.

In the case of a cache, I'd be looking at Interlocked.CompareExchange, personally - i.e. try to update, but if it fails redo the work from scratch (starting from the new value) and try again.