• 单例(Singleton)模式


    一、 单例(Singleton)模式

      单例模式的特点:

      •   单例类只能有一个实例。
      •   单例类必须自己创建自己的唯一实例。
      •   单例类必须给所有其它对象提供这一实例。

      单例模式应用:

      •   每台计算机可以有若干个打印机,但只能有一个Printer Spooler,避免两个打印作业同时输出到打印机。
      •   一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键编号。否则会出现主键重复。

    二、 Singleton模式的结构:

      Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例它。

      除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance方法负责检验并实例化自己,然后存储在静态成员变量中,

      以确保只有一个实例被创建。(关于线程问题以及C#所特有的Singleton将在后面详细论述)。

     三、  在什么情形下使用单例模式:

      使用Singleton模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式。

      反过来,如果一个类可以有几个实例共存,就不要使用单例模式。

    注意:

      不要使用单例模式存取全局变量。这违背了单例模式的用意,最好放到对应类的静态成员中。

      不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。

      Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放,带来问题。

         

       

        /// <summary>
        /// 单例(Singleton)模式
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            { 
                LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
                LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
                LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
                LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
    
                // 同一个实例?
                if ((b1 == b2) && (b2 == b3) && (b3 == b4))
                    Console.WriteLine("Same instance");
    
                //做负载均衡
                Console.WriteLine(b1.Server);
                Console.WriteLine(b2.Server);
                Console.WriteLine(b3.Server);
                Console.WriteLine(b4.Server);
    
                Console.ReadLine();
            }
        }
    
        /// <summary>
        /// 单例模式——现实世界的例子
        /// Singleton 单例(LoadBalancer)
        /// </summary>
        public class LoadBalancer
        {
            private static LoadBalancer balancer;
            private ArrayList servers = new ArrayList();
            private Random random = new Random();
    
            //受保护的 构造函数
            protected LoadBalancer()
            {
                // 可用的服务器列表
                servers.Add("ServerI");
                servers.Add("ServerII");
                servers.Add("ServerIII");
                servers.Add("ServerIV");
                servers.Add("ServerV");
            }
            //方法 定义静态方法确保同时只有一个实例在操作
            public static LoadBalancer GetLoadBalancer()
            {
                //支持多线程应用程序通过
                // “双重检查锁定”模式,避免了
                // 锁定每次方法调用
                //balancer = null;
                if (balancer == null)
                {
                    // 只有一个线程可以获得互斥锁
                    Mutex mutex = new Mutex();
                    mutex.WaitOne();
    
                    if (balancer == null)
                        balancer = new LoadBalancer();
    
                    mutex.Close();
                }
                return balancer;
            }
    
            public string Server
            {
                get
                {
                    // 简单,但有效的随机负载均衡器
                    int r = random.Next(servers.Count);
                    return servers[r].ToString();
                }
            }
        }

     

     

     

     

     

     

     

  • 相关阅读:
    禅道
    centos7 安装redis 出现cc: command not found错误解决
    Linux 安装 redis
    vuex store modules
    vuex store 改造
    vuex store
    Vue axios
    Vue keep-alive
    vue 路由守卫
    vue-router 参数传递
  • 原文地址:https://www.cnblogs.com/dragon-L/p/3685944.html
Copyright © 2020-2023  润新知