Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a reference assignment threadsafe?

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.

like image 400
Steffen Avatar asked Mar 06 '11 09:03

Steffen


People also ask

Is reference assignment Atomic C#?

Reference assignment is atomic. Interlocked. Exchange does not do only reference assignment. It does a read of the current value of a variable, stashes away the old value, and assigns the new value to the variable, all as an atomic operation.

Are references thread safe?

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

Is static thread safe C#?

Thread SafetyStatic variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.

Is static class thread safe?

This can be a little bit confusing, but as it turns out, the static properties on a static class are not thread safe. What this means is that the property is shared between threads.


1 Answers

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.

like image 174
Marc Gravell Avatar answered Sep 19 '22 14:09

Marc Gravell