总结Singleton的实现方法
|
源代码网整理以下第一种 源代码网整理以下 public class Singleton 源代码网整理以下public class Singleton 软件开发网 www.mscto.com 源代码网整理以下 static Singleton() { } 源代码网整理以下 private Singleton() { } 源代码网整理以下 public static Singleton CreateInstance() { return _instance; } 源代码网整理以下第一种方法, 显而易见的, 性能不佳; 而且最好加上一句Thread.MemoryBarrier()。 这是为了线性化内存存取, 避免处理器调整指令顺序导致问题, 至于到底怎么个坏掉法, 我就糊里糊涂了。 但至少从这个角度看, 其实第一种方法, 虽然我们最常用, 如果不加这么一句, 可能反而是不安全的。 源代码网整理以下 第二种方法, 有兄弟说它不是线程安全的, 事实上它是线程安全的, 但不一定是AppDomain安全的。 在同一个AppDomain内, 初始化仅进行一次。但是这种方法有一个细节。 对于没有静态构造函数的类, .NET会加上一个BeforeFieldInit的标志,它的MSDN解释是:Specifies that calling static methods of the type does not force the system to initialize the type. 这就是说, 假设Singleton存在一个静态方法, 比如Singleton.Do(), 这个Do被执行了, 但是_instance并不一定被初始化(当然也不一定不被),只要没有其它条件触发(在后面我们会想一个办法, 保证一定得到这个LazyLoad的效果); 也就是说, 初始化的时间是不固定的; 而且还有别的可能: 比如在程序集被加载, 在该类被某种方式访问, 甚至一个很随机的时刻。 传说中初始化仅仅保证在该字段被访问之前, 由运行时决定, 到底咋回事就不是我关心的范畴了。 软件开发网 www.mscto.com
源代码网整理以下其实早晚本来也是无所谓的, 关键是注意到这一点, 可以避免并没有触发初始化, 可是流程上人脑中有一个预期的行为,进行编程时所造成的不确定性(尽管很难想象能够掉进这个陷阱的场景,估计得特别特殊的应用, 比如你脑海里以为初始化了, 就向其它东西发一个信号, 而且会造成问题等等)。 软件开发网 www.mscto.com 源代码网整理以下如果存在静态构造函数, 那么当这个类的任意成员被访问前, 会进行初始化。 微软这么设计显然是有道理的: 既然写了静态构造器, 那么编程者很显然希望它最早执行, 同时也就会捎带上初始化。 但这种方式会导致, 如果咱们访问Singleton.Do(), 那么所有的字段都会被初始化。也许我们调用Do()的时候因为用不着这个实例, 而且这个实例会耗费很多资源,于是就想尽量Lazy Load用不着就不new, 这样要么使用第一种方法, 或者引出了第三个方法。 源代码网整理以下 public class Singleton 源代码网整理以下 public static Singleton CreateInstance() { return Holder._instance; } 源代码网整理以下 private class Holder 源代码网整理以下 public static readonly Singleton _instance = new Singleton(); 源代码网整理以下回头再说说关于第一种方法的另一个替代品, 这样: 源代码网整理以下public class Singleton 源代码网整理以下 private Singleton() 源代码网整理以下 } 软件开发网 www.mscto.com 源代码网整理以下 public static Singleton CreateInstance() 源代码网整理以下因为Interlocked.CompareExchange是一个原子操作, 所以是线程安全的。不过注意那个new Singleton(), 它会不断的被执行。 如果构造的过程很耗费资源, 这是一个问题。 其实利用delegate, 我们可以有一些新玩法, 把包括第二次及以后进入CreateInstance的开销降到最低; 如果谁想到了可以给我留言。(Update: 我的做法放在了第20楼, 注意脑袋回复中提到的问题, 其实这种做法我一般用在别处完成更贴切的任务, 具体分析日后再说了) 源代码网整理以下最后, 稍加改动, 可以把Singleton成泛型的。不过个人感觉意义不大了, 除非用Singleton的地方太多, 懒得打代码, 也可以考虑。 源代码网推荐 源代码网供稿. |
