zoukankan      html  css  js  c++  java
  • 设计模式学习每天一个——Singleton模式

    单例模式的应用场景:不适宜出现多于一个实例的场景。当我们需要一个公共区域以便于其他各部分进行交流时,我们需要使用单利模式。单例模式就相当于大房间里有很多小房间,但是只有一个卫生间和厨房,众多小房间共用一个卫生间和厨房。我还看到过一个很生动的描述单利模式机制的例子。

    总结:面向对象设计时我们讲求的是封装,是低耦合高内聚。但是世界上的东西不管怎么封装,都是需要相互关联的。所以我们不仅要认识事物,更要清楚的认识事物之间的关联,处理好各个对象间的关系。

    问题:下面这个案例中,私有构造函数什么时候能被调用,公共变量Country什么时候初始化?

    public class Country
        {
            List<string> oCountries = new List<string>();
            public Country()
            {
                oCountries.Add("India");
                oCountries.Add("Nepal");
                oCountries.Add("USA");
                oCountries.Add("UK");
    
            }
            public IEnumerable<string> getCounties()
            {
                return (IEnumerable<string>) oCountries;
            }
        }
    
    
    public sealed class GlobalSingleton
        {
            // object which needs to be shared globally
            public Country Countries = new Country();
    
            // use static variable to create a single instance of the object
            static readonly GlobalSingleton INSTANCE = new GlobalSingleton();
    
            /// This is a private constructor, meaning no outsides have access.
            private GlobalSingleton() 
            { }
            
    public static GlobalSingleton Instance
            {
                get
                {
                  
                    return INSTANCE;
                }
            }       
        }

    Lazy Loading

    Memory barrier issue

    Double-Check-Locking

    Ensure a class only has one instance, and provide a global point of access to it.-[GOF]

    From http://csharpindepth.com/Articles/General/Singleton.aspx

    • A single constructor, which is private and parameterless. This prevents other classes from instantiating it (which would be a violation of the pattern). Note that it also prevents subclassing - if a singleton can be subclassed once, it can be subclassed twice, and if each of those subclasses can create an instance, the pattern is violated. The factory pattern can be used if you need a single instance of a base type, but the exact type isn't known until runtime.
    • The class is sealed. This is unnecessary, strictly speaking, due to the above point, but may help the JIT to optimise things more.
    • A static variable which holds a reference to the single created instance, if any.
    • A public static means of getting the reference to the single created instance, creating one if necessary.   

    Third version - attempted thread-safety using double-check locking

    // Bad code! Do not use!
    public sealed class Singleton
    {
        private static Singleton instance = null;
        private static readonly object padlock = new object();

        Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

    This implementation attempts to be thread-safe without the necessity of taking out a lock every time. Unfortunately, there are four downsides to the pattern:

    • It doesn't work in Java. This may seem an odd thing to comment on, but it's worth knowing if you ever need the singleton pattern in Java, and C# programmers may well also be Java programmers. The Java memory model doesn't ensure that the constructor completes before the reference to the new object is assigned to instance. The Java memory model underwent a reworking for version 1.5, but double-check locking is still broken after this without a volatile variable (as in C#).
    • Without any memory barriers, it's broken in the ECMA CLI specification too. It's possible that under the .NET 2.0 memory model (which is stronger than the ECMA spec) it's safe, but I'd rather not rely on those stronger semantics, especially if there's any doubt as to the safety. Making the instance variable volatile can make it work, as would explicit memory barrier calls, although in the latter case even experts can't agree exactly which barriers are required. I tend to try to avoid situations where experts don't agree what's right and what's wrong!
    • It's easy to get wrong. The pattern needs to be pretty much exactly as above - any significant changes are likely to impact either performance or correctness.
    • It still doesn't perform as well as the later implementations.
  • 相关阅读:
    工作日时间,每10分钟执行一次磁盘空间检查,一旦发现任何分区利用率高 于80%,就发送邮件报警
    编写脚本,使用for和while分别实现192.168.0.0/24网段内,地址是否能够ping通,若ping通则输出"success!",若ping不通则输出"fail!"
    显示统计占用系统内存最多的进程,并排序
    总结IP配置方法
    总结ip分类以及每个分类可以分配的IP数量
    总结描述TCP三次握手四次挥手
    描述TCP和UDP区别
    简述osi七层模型和TCP/IP五层模型
    创建一个至少有两个PV组成的大小为20G的名为testvg的VG;要求PE大小 为16MB, 而后在卷组中创建大小为5G的逻辑卷testlv;挂载至/users目录
    【转载】Centos升级gcc至5.4.0
  • 原文地址:https://www.cnblogs.com/windy86/p/3972392.html
Copyright © 2011-2022 走看看