Is this Comparer class from SSCLI library code ThreadSafe?
public abstract class Comparer<T> : IComparer, IComparer<T>
{
static Comparer<T> defaultComparer;
public static Comparer<T> Default {
get {
Comparer<T> comparer = defaultComparer;
if (comparer == null) {
comparer = CreateComparer();
defaultComparer = comparer;
}
return comparer;
}
}
First, is the Default property thread safe? Isn't it possible that effect of the following statement
comparer = CreateComparer();
might not be visible to threads other than creating thread? So, multiple instances of Compare开发者_高级运维r are constructed?
Is Microsoft doing this for the sake of trading synchronization cost off with the cost of creating multiple objects?
Second why defaultComparer is first assigned to comparer variable first...and then later on swapped? why do Comparer comparer = defaultComparer?
Yes. Multiple comparers do indeed get created, defaultComparer gets assigned multiple times. Not a problem, they are all the same. The garbage collector takes care of the extras. And the atomic assignment guarantee that the CLR offers for object references ensures that the static cannot be read incorrectly.
Yes, it certainly is possible that multiple instances of the comparer are created. Before you can answer whether or not the Default
property is thread-safe we should probably define what we want to be safe. If you only ever want a single instance to be created then it certainly is not thread-safe. However, if you relax your requirement to allow for multiple instances as long as some instance is returned then it certainly does that.
I would say the reasoning behind this decision was based partly on the fact that the IComparer
instance is stateless. That means from a callers perspective it really does not matter which instance the caller grabs because they all look and operate the same. In other words, it really would not matter if a single thread repeatedly read Default
and got a different instance each time.
精彩评论