`

Singleton Pattern

阅读更多

单件模式:(Singleton pattern)
1.目的
1) 在全局范围内控制一个对象只能有一个唯一的实例 


2.作用
具体程序设计中往往需要保证一个类只能有一个实例
如:
一个客户端只能有一个数据库连接;
为了节省资源,配置文件只能被加载一次;
虽然又多个串行端口,但使能又一个COM1实例(比如对嵌入式编程,对外设开发驱动程序等等)


3.单件模式的机制
1) 单件模式保证只能常见对象的唯一一个实例
2) 单件模式提供一个全局访问点:(不让外边来创建实例,提供一个方法来获取我的实例,该方法就是全局的访问点)
3) 通过静态变量C#,Java中(static),VB中(Shared)来实现唯一性.(静态成员在全局范围内是唯一的不属于某个对象属于类)


4.多线程下的单件模式 (多线程下存在多线程同步的问题,如果不控制多线程同步,那么多线程同时访问单件模式这个方法,可能会生成不唯一的实例,所以需要控制多线程同步问题)
1) 在多线程下,保证一个类只有唯一一个实例
2) C#->lock,Java->synchronized
开始,结束.public static load()

3)为什么在多线程下可能会生成不唯一的实例呢?
假如有两个线程,同时访问GetInstances()这个方法,第一个线程执行到singleton = new Singleton();这行
第二个线程执行到 { 这行,很明显会产生两个实例了. 

 

 

ClassDiagram:

 

 

 

SequenceDiagram:

 

 

 

单线程下的单例示例:

    class Program 
    { 
        static void Main(string[] args) 
        { 

            Singleton single1 = Singleton.GetInstances(); 

            Singleton single2 = Singleton.GetInstances(); 

            //结果为ture,这样一个简单的单例模式就完成了!!! 
            Console.WriteLine(single1==single2);  
           
            Console.ReadKey(); 
        } 
    } 

    /// 
    /// 单线程下的单例模式 
    /// 
    class Singleton 
    { 
        //用静态变量的目的是为了保证唯一性(静态变量是唯一的,在类中共享的不属于某个对象) 
        public static Singleton singleton = null; 

        private Singleton() 
        { 
           
        } 
         //饿汉式写法.这种写法可能在多个线程访问事出现两个对象(虽然可能行很小!)
        public static Singleton GetInstances() 
        { 
            if (singleton==null) 
            { 
                singleton = new Singleton(); 
            } 
            return singleton; 
        } 

    } 

  

  

   

 class Client
    {
        static void Main(string[] args)
        {
            Singleton s1 = Singleton.GetInstance();
            Singleton s2 = Singleton.GetInstance();

            Console.WriteLine(s1 == s2);

            Console.ReadKey();
        }
    }

    public class Singleton
    {  //静态成员在类初始化时只会被加载一次.
        private static Singleton singleton = new Singleton();

        //懒汉式写法(这种方式多线程下不会出现两个对象.)
        public static Singleton GetInstance()
        {
            return singleton;
        }
    }

 

 

  

   多线程下的示例:

        static void Main(string[] args)
        {

            Singleton single1 = Singleton.GetInstances();

            Singleton single2 = Singleton.GetInstances();
            //结果为ture,这样一个简单的单例模式就完成了!!!
            Console.WriteLine(single1 == single2);

            Console.ReadKey();

        }
    }

    /// <summary>
    /// 单线程下的单例模式
    /// </summary>
    class Singleton
    {
        //用静态变量的目的是为了保证唯一性(静态变量是唯一的,在类中共享的不属于某个对象)
        public static Singleton singleton = null;

        private Singleton()
        {

        }


        public static Singleton GetInstances()
        {
            //lock(同步)的作用:保证在lock代码块中的代码在同一时刻只能有同一个线程可以访问它
            /*这和数据库的锁一个意思,通俗的讲当一个线程执行到lock里的代码块,第二个线程也来了
            来了后被lock挡住,档在外面了,等第一个线程执行完以后,才去执行第二个线程(线程同步的概念) 
            */
            lock (typeof(Singleton))
            {
                if (singleton == null)
                {
                    singleton = new Singleton();
                }
                return singleton;
            }
        }
    }

  

  

using System;
using System.Collections;
using System.Threading;

// "Singleton"
class LoadBalancer
{
  // Fields
  private static LoadBalancer balancer;
  private ArrayList servers = new ArrayList();
  private Random random = new Random();

  // Constructors (protected)
  protected LoadBalancer()
  {
    // List of available servers
    servers.Add( "ServerI" );
    servers.Add( "ServerII" );
    servers.Add( "ServerIII" );
    servers.Add( "ServerIV" );
    servers.Add( "ServerV" );
  }

  // Methods
  public static LoadBalancer GetLoadBalancer()
  {
    // Support multithreaded applications through
    // "Double checked locking" pattern which avoids
    // locking every time the method is invoked
    if( balancer == null )
    {
      // 只允许一个线程访问
      Mutex mutex = new Mutex();
      mutex.WaitOne();

      if( balancer == null )
        balancer = new LoadBalancer();

      mutex.Close();
    }
    return balancer;
  }

  // Properties
  public string Server
  {
    get
    {
      // Simple, but effective random load balancer
      int r = random.Next( servers.Count );
      return servers[ r ].ToString();
    }
  }
}

/**//// <summary>
/// SingletonApp test
/// </summary>
///
public class SingletonApp
{
  public static void Main( string[] args )
  {
    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" );

    // Do the load balancing
    Console.WriteLine( b1.Server );
    Console.WriteLine( b2.Server );
    Console.WriteLine( b3.Server );
    Console.WriteLine( b4.Server );
  }
}

 

  

C#的独特语言特性决定了C#拥有实现Singleton模式的独特方法。这里不再赘述原因,给出几个结果:

方法一:

下面是利用.NET Framework平台优势实现Singleton模式的代码:

sealed class Singleton
{
   private Singleton();
   public static readonly Singleton Instance=new Singleton();
}

 

这使得代码减少了许多,同时也解决了线程问题带来的性能上损失。那么它又是怎样工作的呢?

注意到,Singleton类被声明为sealed,以此保证它自己不会被继承,其次没有了Instance的方法,将原来_instance成员变量变成public readonly,并在声明时被初始化。通过这些改变,我们确实得到了Singleton的模式,原因是在JIT的处理过程中,如果类中的static属性被任何方法使用时,.NET Framework将对这个属性进行初始化,于是在初始化Instance属性的同时Singleton类实例得以创建和装载。而私有的构造函数和readonly(只读)保证了Singleton不会被再次实例化,这正是Singleton设计模式的意图。

不过这也带来了一些问题,比如无法继承,实例在程序一运行就被初始化,无法实现延迟初始化等。

 

方法二:

既然方法一存在问题,我们还有其它办法。

public sealed class Singleton
{
  Singleton()
  {
  }

  public static Singleton GetInstance()
  {
    return Nested.instance;
  }
    
  class Nested
  {
    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Nested()
    {
    }

    internal static readonly Singleton instance = new Singleton();
  }
}

  

 

    java示例:

public class Singleton {

  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
      if (instance == null){
        instance = new Singleton();
        }
      return instance;   
    }

}

 

 

  

 

  • 大小: 35.3 KB
  • 大小: 4.2 KB
分享到:
评论

相关推荐

    singleton pattern

    singleton pattern 的定义 主要应用方法 优缺点 通过代码 具体分析解释

    Singleton pattern单例模式应用

    ### Singleton Pattern 单例模式应用详解 #### 一、单例模式概述 单例模式(Singleton Pattern)是一种常用的软件设计模式,在系统中确保某个类只有一个实例,并提供一个全局访问点。这种模式通常用于控制资源的...

    通过go语言实现单例模式(Singleton Pattern).rar

    在Go语言中,实现单例模式(Singleton Pattern)通常涉及确保一个类只有一个实例,并提供一个全局访问点来获取该实例。由于Go语言没有传统的类和对象概念,但具有结构体(struct)和函数,我们可以通过使用包级变量...

    前端大厂最新面试题-Singleton Pattern.docx

    Singleton Pattern单例模式详解 Singleton Pattern单例模式是一种创建型设计模式,提供了一种创建对象的最佳方式。该模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建在应用程序运行...

    单例模式 Singleton Pattern

    ### 单例模式 Singleton Pattern #### 概述 单例模式是一种常见的设计模式,属于创建型模式之一。这种模式的核心在于确保某个类只有一个实例存在,并且提供一个全局访问点来获取该实例。单例模式在Java开发中尤其...

    Singleton Pattern 源码

    单例模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如控制资源的唯一性、全局配置对象或者缓存服务等。本篇文章将深入探讨...

    设计模式 之 “单例模式[Singleton Pattern]”

    **单例模式(Singleton Pattern)**是软件设计模式中的一种基础模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如配置管理、线程池、数据库连接池等,这些都...

    Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现

    单件模式(Singleton pattern)是设计模式中的一种结构型模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于系统中需要频繁创建和销毁的对象,如日志服务、线程池或者数据库连接等...

    Android SingletonPatternDemo

    Java据说有23种设计模式,Android的设计模式肯定是由Java来引申出来的。这里不讨论有多少人全会,有多少种设计模式会使用到,我们来讲下其中用得最多的也就是人人都知道的...这里是一个简单的SingletonPatternDemo。

    c++-设计模式之单例模式(Singleton Pattern)

    单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于需要全局共享资源的场景,比如配置管理、日志记录等。 单例模式的组成 私有构造函数:防止外部...

    创建型模式之单例模式(Singleton Pattern)

    private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } } ``` 2. 懒汉式(Lazy Initialization):在第一次需要时...

    C#单例模式(Singleton Pattern)详解

    C#单例模式(Singleton Pattern)是一种常用的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。下面我们将详细介绍C#单例模式的定义、实现和优化。 单例模式的定义: 单例模式的主要目的是确保一个...

    C#单例模式(Singleton Pattern)实例教程

    本文以实例形式讲述了C#单例模式(Singleton Pattern)的实现方法,分享给大家供大家参考。具体实现方法如下: 一般来说,当从应用程序全局的角度来看,如果只允许类的一个实例产生,就可以考虑单例模式。 1.即时加载...

    23种设计模式-C_版本

    设计模式 - Singleton Pattern 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。这就是 Singleton Pattern 的设计动机。 Singleton ...

    单例模式Singleton

    单例模式(Singleton Pattern)是一种常用的软件设计模式,它的核心思想是确保一个类在整个应用程序中只有一个实例存在,并提供一个全局访问点来获取这个实例。这种模式在很多场景下非常有用,比如管理系统资源、...

    设计模式_单例模式.zip

    private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } ``` ...

    单例模式(Singleton Pattern)

    private static final Singleton1 instance = new Singleton1(); private Singleton1() {} public static Singleton1 getInstance() { return instance; } } ``` - 静态代码块方式: ```java public class...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    3、单例模式SINGLETON PATTERN 4、多例模式MULTITION PATTERN 5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT FACTORY PATTERN 7、门面模式FACADE PATTERN 8、适配器模式ADAPTER PATTERN 9、模板...

    Laravel开发-singleton-pattern

    在`singleton-pattern-master`这个压缩包中,可能包含了一个示例项目或者一个库,它演示了如何在Laravel中实现和使用单例模式。可能的目录结构包括源代码文件、配置文件、示例测试等,帮助开发者更好地理解和应用...

    C#版 24种设计模式

    备忘录模式(Memento Pattern) 策略模式(Strategy Pattern) 抽象工厂模式(Abstract Factory Pattern) 代理模式(Proxy Pattern) 单例模式(Singleton Pattern) 迭代器模式(Iterator Pattern) 访问者模式(Visitor ...

Global site tag (gtag.js) - Google Analytics