问题描述
|
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;
}
}
首先,Default属性线程安全吗?
以下语句的效果是否可能
comparer = CreateComparer();
可能对创建线程以外的线程不可见?
那么,构造了多个Comparer实例吗?
微软这样做是出于交易同步成本与交易成本之间的关系吗?
创建多个对象?
第二,为什么先将defaultComparer分配给比较器变量,然后再交换?
为什么比较器比较器= defaultComparer?
解决方法
是。实际上确实创建了多个比较器,对defaultComparer进行了多次分配。没问题,它们都是一样的。垃圾收集器负责额外的工作。而且CLR为对象引用提供的原子分配保证可以确保不会错误地读取静态。
, 是的,肯定有可能创建比较器的多个实例。在您可以回答
Default
属性是否是线程安全的之前,我们可能应该定义我们想要的安全性。如果您只想创建一个实例,那么它肯定不是线程安全的。但是,如果您放宽了允许返回多个实例的要求,那么一定会这样做。
我想说这个决定背后的原因部分是基于“ 3”实例是无状态的事实。这意味着从呼叫者的角度来看,呼叫者抓住哪个实例并不重要,因为它们看起来和操作相同。换句话说,如果单个线程重复读取Default
并且每次都获得不同的实例,则实际上并不重要。