By default non-static methods have their own instance of variables for each thread when accessed via multiple threads, thus rendering them thread safe if they do not include a public variable etc.
On the other hand, variables in static methods are shared amongst threads rendering them non-thread safe by default.
Say, I have a class, having no static variables or methods whatsoever.
public class Profile {
private ConcurrentDictionary<int, int> cache =
new ConcurrentDictionary<int, int>();
public AddToCache() {
}
public RemoveToCache() {
}
public DoSomethingThatShouldBeThreadSafe() {
}
}
But then I create a static object from this class.
public static Profile objProfile = new Profile();
And then, objProfile is accessed with multiple threads.
The question is, are the methods of Profile class, AddToCache, RemoveFromCache and DoSomethingThatShouldBeThreadSafe, going to be thread safe or not when used through objProfile? Are their variables will be shared amongst threads, even if they are not static because the whole instance of the class is static?
As long as you only access the
ConcurrentDictionary<>instancecache, and don’t overwritecachewith a new instance in one ofProfile-methods it is threadsafe.Because of the second point, it’s better to mark it
readonly,because this says that you can write this member only during instantiation of
Profile.EDIT:
Although the
ConcurrentDictionary<>itself is thread-safe, you still have the problem of non-atomicity of compound operations. Let’s take a look at two possibleGetFromCache()methods.only the second one is atomic, because it uses the
ConcurrentDictionary<>.TryGetValue()method.EDIT 2 (answer to 2nd comment of Chiao):
ConcurrentDictionary<>has theGetOrAdd()method, which takes aFunc<TKey, TValue>delegate for non-existing values.