Singleton: How should it be used

后端 未结 24 1920
Happy的楠姐
Happy的楠姐 2020-11-22 04:57

Edit: From another question I provided an answer that has links to a lot of questions/answers about singletons: More info about singletons here:

So I have read th

24条回答
  •  醉话见心
    2020-11-22 05:18

    I think this is the most robust version for C#:

    using System;
    using System.Collections;
    using System.Threading;
    
    namespace DoFactory.GangOfFour.Singleton.RealWorld
    {
    
      // MainApp test application
    
      class MainApp
      {
        static void Main()
        {
          LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
    
          // Same instance?
          if (b1 == b2 && b2 == b3 && b3 == b4)
          {
            Console.WriteLine("Same instance\n");
          }
    
          // All are the same instance -- use b1 arbitrarily
          // Load balance 15 server requests
          for (int i = 0; i < 15; i++)
          {
            Console.WriteLine(b1.Server);
          }
    
          // Wait for user
          Console.Read();    
        }
      }
    
      // "Singleton"
    
      class LoadBalancer
      {
        private static LoadBalancer instance;
        private ArrayList servers = new ArrayList();
    
        private Random random = new Random();
    
        // Lock synchronization object
        private static object syncLock = new object();
    
        // Constructor (protected)
        protected LoadBalancer()
        {
          // List of available servers
          servers.Add("ServerI");
          servers.Add("ServerII");
          servers.Add("ServerIII");
          servers.Add("ServerIV");
          servers.Add("ServerV");
        }
    
        public static LoadBalancer GetLoadBalancer()
        {
          // Support multithreaded applications through
          // 'Double checked locking' pattern which (once
          // the instance exists) avoids locking each
          // time the method is invoked
          if (instance == null)
          {
            lock (syncLock)
            {
              if (instance == null)
              {
                instance = new LoadBalancer();
              }
            }
          }
    
          return instance;
        }
    
        // Simple, but effective random load balancer
    
        public string Server
        {
          get
          {
            int r = random.Next(servers.Count);
            return servers[r].ToString();
          }
        }
      }
    }
    

    Here is the .NET-optimised version:

    using System;
    using System.Collections;
    
    namespace DoFactory.GangOfFour.Singleton.NETOptimized
    {
    
      // MainApp test application
    
      class MainApp
      {
    
        static void Main()
        {
          LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
          LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
    
          // Confirm these are the same instance
          if (b1 == b2 && b2 == b3 && b3 == b4)
          {
            Console.WriteLine("Same instance\n");
          }
    
          // All are the same instance -- use b1 arbitrarily
          // Load balance 15 requests for a server
          for (int i = 0; i < 15; i++)
          {
            Console.WriteLine(b1.Server);
          }
    
          // Wait for user
          Console.Read();    
        }
      }
    
      // Singleton
    
      sealed class LoadBalancer
      {
        // Static members are lazily initialized.
        // .NET guarantees thread safety for static initialization
        private static readonly LoadBalancer instance =
          new LoadBalancer();
    
        private ArrayList servers = new ArrayList();
        private Random random = new Random();
    
        // Note: constructor is private.
        private LoadBalancer()
        {
          // List of available servers
          servers.Add("ServerI");
          servers.Add("ServerII");
          servers.Add("ServerIII");
          servers.Add("ServerIV");
          servers.Add("ServerV");
        }
    
        public static LoadBalancer GetLoadBalancer()
        {
          return instance;
        }
    
        // Simple, but effective load balancer
        public string Server
        {
          get
          {
            int r = random.Next(servers.Count);
            return servers[r].ToString();
          }
        }
      }
    }
    

    You can find this pattern at dotfactory.com.

提交回复
热议问题