C#实现单例模式的多种方式

什么是单例模式?

这里我就不做过多的解释了, 毕竟关于Singleton的资料实在是太多太多了。点击这里

简单的思路就是, 创建对象单例的动作转移到另外的行为上面, 利用一个行为去创建对象自身, 如下:

public class Singleton
    {
       private Sington() { }
        private static Singleton _Singleton = null;
        public static Singleton CreateInstance()
        {
            if (_Singleton == null)
            {
             Console.WriteLine("被创建");
             _Singleton = new Singleton();
            }
            return _Singleton;
        }
    }

这样写看上去是没有问题, 但是有没有那种可能, 同时两个动作都判断这个对象为空, 那么这个对象就会被创建2次?是的, 多线程中, 这样是无法保证单例。

就像这样, 同时创建多个线程去创建这个对象实例的时候, 会被多次创建, 这个时候, 对代码改进一下。

public class Singleton
    {
       private Sington() { }
        private static Singleton _Singleton = null;
        private static object Singleton_Lock = new object(); //锁同步
        public static Singleton CreateInstance()
        {
                lock (Singleton_Lock)
                {
            Console.WriteLine("路过");
                    if (_Singleton == null)
                    {
              Console.WriteLine("被创建");
                        _Singleton = new Singleton();
                    }
                }
            return _Singleton;
        }
    }

调试代码:

                TaskFactory taskFactory = new TaskFactory();
                List<Task> taskList = new List<Task>();

                for (int i = 0; i < 5; i++)
                {
                    taskList.Add(taskFactory.StartNew(() =>
                     {
                         Singleton singleton = Singleton.CreateInstance();
                     }));
                }

结果:

上面, 我们创建了多个线程,同时去创建这个对象的实例, 在第二次,对象命名已经被创建了, 尽管只创建了一次满足了我们的需求, 但是我们已知对象被创建了, 还需要进来做不必要的动作吗?

我们都知道, 同步锁为了达到预期的效果, 也是损耗了性能的, 那么下面的输出, 很显然是没必要的动作, 所以我们优化一下。

    public class Singleton
    {
        private static Singleton _Singleton = null;
        private static object Singleton_Lock = new object();
        public static Singleton CreateInstance()
        {
            if (_Singleton == null) //双if +lock
            {
                lock (Singleton_Lock)
                {
                    Console.WriteLine("路过。");
                    if (_Singleton == null)
                    {
                        Console.WriteLine("被创建。");
                        _Singleton = new Singleton();
                    }
                }
            }
            return _Singleton;
        }
    }

结果:

很显然, 这样达到了我们的预期, 对象在被创建后, 就没必要做多余的行为。

利用静态变量实现单例模式

 public sealed class Singleton
    {
        private Singleton() { }

        private static readonly Singleton singleInstance = new Singleton();

        public static Singleton GetInstance
        {
            get
            {
                return singleInstance;
            }
        }
    }

是不是觉得很优雅, 利用静态变量去实现单例, 由CLR保证,在程序第一次使用该类之前被调用,而且只调用一次

PS: 但是他的缺点也很明显, 在程序初始化后, 静态对象就被CLR构造了, 哪怕你没用。

利用静态构造函数实现单例模式

 public class SingletonSecond
    {
        private static SingletonSecond _SingletonSecond = null;

        static SingletonSecond()
        {

            _SingletonSecond = new SingletonSecond();
        }

        public static SingletonSecond CreateInstance()
        {
            return _SingletonSecond;
        }
    }

静态构造函数:只能有一个,无参数的,程序无法调用 。

同样是由CLR保证,在程序第一次使用该类之前被调用,而且只调用一次。同静态变量一样, 它会随着程序运行, 就被实例化, 同静态变量一个道理。

单例模式中的延迟加载

延迟加载或延迟加载是一种设计模式,或者您可以说这是一个概念,通常用于将对象的初始化延迟到需要时。因此,延迟加载的主要目标是按需加载对象,或者您可以根据需要说出对象。

作为 .NET Framework 4.0 的一部分引入的惰性关键字为惰性初始化(即按需对象初始化)提供了内置支持。如果要使对象(如 Singleton)以延迟初始化,则只需将对象的类型(单例)传递给lazy关键字,如下所示。

private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton());
 public sealed class Singleton
     {
         private Singleton()
         {}

         private static readonly Lazy<Singleton> Instancelock =
                     new Lazy<Singleton>(() => new Singleton());

         public static Singleton GetInstance
         {
             get
             {
                 return Instancelock.Value;
             }
         }
     }

到此这篇关于C#实现单例模式的多种方式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#实现单例模式的几种方法总结

    介绍 单例模式是软件工程学中最富盛名的设计模式之一.从本质上看,单例模式只允许被其自身实例化一次,且向外部提供了一个访问该实例的接口.通常来说,单例对象进行实例化时一般不带参数,因为如果不同的实例化请求传递的参数不同的话会导致问题的产生.(若多个请求都是传递的同样的参数的话,工厂模式更应该被考虑) C#中实现单例有很多种方法,本文将按顺序介绍非线程安全.完全懒汉式.线程安全和低/高性能集中版本. 在所有的实现版本中,都有以下几个共同点: 唯一的.私有的且无参的构造函数,这样不允许外部类进行实例化

  • 浅谈C#单例模式的实现和性能对比

    简介 单例指的是只能存在一个实例的类(在C#中,更准确的说法是在每个AppDomain之中只能存在一个实例的类,它是软件工程中使用最多的几种模式之一.在第一个使用者创建了这个类的实例之后,其后需要使用这个类的就只能使用之前创建的实例,无法再创建一个新的实例.通常情况下,单例会在第一次被使用时创建.本文会对C#中几种单例的实现方式进行介绍,并分析它们之间的线程安全性和性能差异. 单例的实现方式有很多种,但从最简单的实现(非延迟加载,非线程安全,效率低下),到可延迟加载,线程安全,且高效的实现,它们

  • c# 单例模式的实现

    记一下学习单例模式的笔记: 单例就是要保证该类仅有一个实例.实现完全封闭的单例(外部不能new)其实就要两点要求: 全局访问:需要一个该类型的全局静态变量,每次获取实例时都要判断它是否null,不存在new,存在通过一个方法直接返回该值获取实例来保证对象唯一: 实例化控制:new实例不能外部new.造成实例不唯一,需要一个私有构造器禁用共有构造器. 根据new实例的时机,分为饿汉式和懒汉式: 一. 饿汉式单例:静态变量初始化时new 特点:加载时new,一开始全局就存在该唯一实例,每次用到只要获

  • c#设计模式之单例模式的实现方式

    场景描述 单例模式对于我们来说一点也不模式,是一个常见的名称,单例模式在程序中的实际效果就是:确保一个程序中只有一个实例,并提供一个全局访问点,节省系统资源 单例模式无论是在实际开发中还是在软件应用中比较常见,比如,windows系统的任务管理器.IIS的HttpApplication.实际项目中的日志组件等等 实现方式 单例模式为了实现一个实例,那么只有不把实例创建暴露出去,只通过类本身来创建实例,为了实现效果,需要定义一个私有构造函数 单例模式实现方式有:饿汉式.懒汉式.双重验证式.静态内部

  • c# 单例模式的实现方法

    单例模式大概是所有设计模式中最简单的一种,如果在面试时被问及熟悉哪些设计模式,你可能第一个答的就是单例模式. 单例模式的实现分为两种:饿汉式和懒汉式.前者是在静态构造函数执行时就立即实例化,后者是在程序执行过程中第一次需要时再实例化.两者有各自适用的场景,实现方式也都很简单,唯一在设计时要考虑的一个问题就是:实例化时需要保证线程安全. 饿汉式 饿汉式实现很简单,在静态构造函数中立即进行实例化: public class Singleton { private static readonly Si

  • c#单例模式(Singleton)的6种实现

    1.1.1 摘要 在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的--单例模式(Singleton). 使用频率高 单件模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.1.2 正文 图1单例模式(Singleton)结构图 单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户

  • C#窗口实现单例模式的方法

    主要是应对这种需求:软件只允许启动一次. 将这个问题转化一下,可以这样描述:对于一个软件,在启动一个进程之后,不允许启动其它进程,如果第二次打开程序,就把已经启动的那个进程的窗口放到最前端显示. C# winfrom应用在启动之后会首先执行program.cs里的代码,所以需要在这里下手.启动后,检测是否有相同进程名的进程,如果有,就把那个进程的窗口提到前端,然后关闭自己. 用法:把你的program.cs改造成这个样子: static class Program { //windows api

  • C#实现单例模式的多种方式

    什么是单例模式? 这里我就不做过多的解释了, 毕竟关于Singleton的资料实在是太多太多了.点击这里 简单的思路就是, 创建对象单例的动作转移到另外的行为上面, 利用一个行为去创建对象自身, 如下: public class Singleton { private Sington() { } private static Singleton _Singleton = null; public static Singleton CreateInstance() { if (_Singleton

  • 在android开发中进行数据存储与访问的多种方式介绍

    数据存储与访问 很多时候我们的软件需要对处理后的数据进行存储或再次访问.Android为数据存储提供了多种方式,分别有如下几种: 文件 SharedPreferences SQLite数据库 内容提供者(Content provider) 网络 使用文件进行数据存储 首先给大家介绍使用文件如何对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的. 复制代码 代码如下: public clas

  • iOS模仿微信长按识别二维码的多种方式

    参考:https://github.com/nglszs/BCQRcode 方式一: #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end ************** #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDid

  • vue绑定设置属性的多种方式(5)

    vue系列教程第五篇,即绑定设置属性的多种方式,具体内容如下 一.设置属性的值: {{data中的数据}} window.onload = function () { var c = new Vue({ el : '#box', data : { url : 'https://img6.bdstatic.com/img/image/smallpic/weijupaishefensetu.jpg' } }); } <div id="box"> <img src=&quo

  • JS中多种方式创建对象详解

    1.内置对象创建 var girl=new Object(); girl.name='hxl'; console.log(typeof girl); 2.工厂模式,寄生构造函数模式 function Person(name){ var p=new Object();//内部进行实例化 p.name=name; p.say=function(){ console.log('my name is '+ p.name); } return p;//注:一定要返回 } var girl=Person('

  • 5种Python单例模式的实现方式

    本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下 所谓单例,是指一个类的实例从始至终只能被创建一次. 方法1: 如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单.Python中类是通过__new__来创建实例的: class Singleton(object): def __new__(cls,*args,**kwargs): if not hasattr(cls,'_inst'): cls._inst=super(Singleton,cl

  • 使用多种方式实现遍历HashMap的方法

    今天讲解的主要是使用多种方式来实现遍历HashMap取出Key和value,首先在java中如果想让一个集合能够用for增强来实现迭代,那么此接口或类必须实现Iterable接口,那么Iterable究竟是如何来实现迭代的,在这里将不做讲解,下面主要讲解一下遍历过程. //定义一个泛型集合 Map<String, String> map = new HashMap<String, String>(); //通过Map的put方法向集合中添加数据 map.put("001&

  • 多种方式实现js图片预览

    先贴代码,之后完善: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta

  • Spring实现IoC的多种方式小结

    控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法.没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了. IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现Io

  • 详解idea打包jar的多种方式

    这里总结出用IDEA打包jar包的多种方式,以后的项目打包Jar包可以参考如下形式: 用IDEA自带的打包形式 用Maven插件maven-shade-plugin打包 用Maven插件maven-assembly-plugin打包 用IDEA自带的打包方式: 打开IDEA的file -> Project Structure,进入项目配置页面.如下图: 点击Artifacts,进入Artifacts配置页面,点击 + ,选择如下图的选项. 进入Create JAR from Modules页面,

随机推荐