什么是单例模式?

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

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

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

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

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

    public class Singleton
{
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 class SingletonThird
{
/// <summary>
/// 静态变量
/// </summary>
private static SingletonThird _SingletonThird = new SingletonThird(); public static SingletonThird CreateInstance()
{
return _SingletonThird;
}
}

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

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

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

    public class SingletonSecond
{
private static SingletonSecond _SingletonSecond = null; static SingletonSecond()
{

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

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

同样是由CLR保证,在程序第一次使用该类之前被调用,而且只调用一次

同静态变量一样, 它会随着程序运行, 就被实例化, 同静态变量一个道理。

C# 单例模式的多种简单实现的更多相关文章

  1. Singleton单例模式是最简单的设计模式,它的主要作用是保证在程序执行生命周期中,使用了单类模式的类仅仅能有一个实例对象存在。

                                                                                                        ...

  2. JS实现单例模式的多种方案

    JS实现单例模式的多种方案 今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6 ...

  3. 单例模式,多种实现方式JAVA

    转载请注明出处:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private stati ...

  4. C#单例模式的多种写法

    它的主要特点不是根据客户程序调用生成一个新的实例,而是控制某个类型的实例数量-唯一一个.(<设计模式-基于C#的工程化实现及扩展>,王翔).也就是说,单例模式就是保证在整个应用程序的生命周 ...

  5. Python之单例模式的多种实现

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  6. JAVA:将反射技术应用于工厂模式(Factory)和单例模式(Singleton)的简单代码

    反射技术大量用于Java设计模式和框架技术,最常见的设计模式就是工厂模式(Factory)和单例模式(Singleton). 参考URL: http://blog.csdn.net/xiaohai79 ...

  7. java中全面的单例模式多种实现方式总结

    单例模式的思想 想整理一些 java 并发相关的知识,不知道从哪开始,想起了单例模式中要考虑的线程安全,就从单例模式开始吧. 以前写过单例模式,这里再重新汇总补充整理一下,单例模式的多种实现. 单例模 ...

  8. 【python之路33】开发模式单例模式及简单的服务器请求框架原理

    1.单例模式指的是创建单个实例,例如:数据库连接池中包含10个数据库连接,用户访问数据时随机从连接池中拿出一个进行连接,其他用户再次访问时不再创建对象进行连接 #!usr/bin/env python ...

  9. 23种设计模式--单例模式-Singleton

    一.单例模式的介绍 单例模式简单说就是掌握系统的至高点,在程序中只实例化一次,这样就是单例模式,在系统比如说你是该系统的登录的第多少人,还有数据库的连接池等地方会使用,单例模式是最简单,最常用的模式之 ...

随机推荐

  1. python爬虫之requests库介绍(二)

    一.requests基于cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到我们 ...

  2. JDBC注册驱动的三种方式(MySQL)

    第一种:通过反射Class.forName("com.mysql.jdbc.Driver"); 第二种:通过DriverManage的静态方法DriverManager.regis ...

  3. FileCopy方法

    复制文件. 语法 FileCopy源,目标 FileCopy 语句语法包含以下命名参数: 部分 说明 source 必需. 指定要复制的文件的名称的字符串表达式. _源_可能包含目录或文件夹,和驱动器 ...

  4. let与var区别

    <!DOCTYPE html> <html> <head> <title>let与var区别</title> <meta charse ...

  5. 微信小程序video视频组件

    支持mp4和m3u8的视频格式,其中mp4的需要是h264的视频编码 .1.如果您使用video组件是mp4的但不能播放,大部分是由于编码的问题,当然排除文件不存在等这些客观的因素条件.2.如果使用m ...

  6. vue 子组件传值给父组件

    子组件通过this.$emit("event",[args,....]),传值给父组件 HTML部分: <div id="app"> <tmp ...

  7. CHAPTER 8 Out of Darkness 第8章 走出黑暗

    CHAPTER 8 Out of Darkness 第8章 走出黑暗 We expect scientists to be trying to discover new things, and for ...

  8. 国密算法--Openssl 实现国密算法(加密和解密)

    上一次讲了产生密钥,这次我们讲一下加密解密的实现. 先说一下加密解密的流程,一下这些内容都是从国密局发布的国密标准文档里面摘录出来的.大家可以去国密局的网站上自己下载. 下列符号适用于本部分. A,B ...

  9. 利用Elasticsearch搭建全球域名解析记录

    前言 数据来源,由Rapid7收集并提供下载https://scans.io/study/sonar.fdns 下载Elasticsearch 2.3 ElasticSearch是一个基于Lucene ...

  10. JVM新生代老年代详解

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...