3
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;
            }
        }

首先,默认属性线程安全吗?以下语句的效果是不是可能

comparer = CreateComparer(); 

除了创建线程之外,线程可能看不到?那么,是否构造了多个 Comparer 实例?

Microsoft 这样做是为了用创建多个对象的成本来交换同步成本吗?

其次,为什么首先将 defaultComparer 首先分配给比较器变量……然后再进行交换?为什么Comparer comparer = defaultComparer?

4

2 回答 2

1

是的。确实创建了多个比较器,defaultComparer 被多次分配。没问题,它们都是一样的。垃圾收集器负责处理额外内容。并且 CLR 为对象引用提供的原子分配保证确保不会错误地读取静态。

于 2011-03-16T23:47:33.950 回答
0

是的,当然可以创建比较器的多个实例。在您回答该Default属性是否是线程安全的之前,我们可能应该定义我们想要安全的内容。如果您只想创建一个实例,那么它肯定不是线程安全的。但是,如果您放宽要求以允许多个实例,只要返回某个实例,那么它肯定会这样做。

我想说这个决定背后的原因部分是基于IComparer实例是无状态的这一事实。这意味着从调用者的角度来看,调用者抓取哪个实例并不重要,因为它们看起来和操作都相同。换句话说,如果一个线程重复读取Default并且每次都得到一个不同的实例,这并不重要。

于 2011-06-13T17:53:51.197 回答