`

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)是一种常用的软件设计模式,在系统中确保某个类只有一个实例,并提供一个全局访问点。这种模式通常用于控制资源的...

    前端大厂最新面试题-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 ...

    常见设计模式的解读和对应代码示例,包括设计原则和软件工程中类之间的依赖关系

    单例模式(Singleton Pattern) 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) 结构型模式(Structural Pattern) 适配器模式(Adapter/...

Global site tag (gtag.js) - Google Analytics