zoukankan      html  css  js  c++  java
  • 单例(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();
                }
            }
        }

     

     

     

     

     

     

     

  • 相关阅读:
    Can you answer these queries?(HDU4027+势能线段树)
    Tunnel Warfare(HDU1540+线段树+区间合并)
    Computer(HDU2196+树形dp+树的直径)
    Anniversary party(树上dp+HDU1520)
    2018 Multi-University Training Contest 1-1002 -Balanced Sequence(括号匹配+贪心)
    暑假集训——cf热身赛部分题有感加其题解
    Educational Codeforces Round 47 (Rated for Div. 2) 题解
    计蒜客 Goldbach Miller_Rabin判别法(大素数判别法)
    多种方法过Codeforces Round #270的A题(奇偶法、打表法和Miller_Rabin(这个方法才是重点))
    Codeforces Round #494 (Div. 3)
  • 原文地址:https://www.cnblogs.com/dragon-L/p/3685944.html
Copyright © 2011-2022 走看看