单例类

有时候我们不要在一个程序中创建太多的实例。只想用一个全局的实例和一个可以访问点。那么我们需要一个单例类。

因为是单例类啦,所以构造函数肯定是私有的。

需要了解的术语

懒汉式

顾名思义。什么时候用就什么时候去new实例。

比如:

  1. class Singleton
  2. {
  3. private static Singleton instance = null;
  4.  
  5. private Singleton()
  6. {
  7.  
  8. }
  9.  
  10. public static Singleton Instance
  11. {
  12. get
  13. {
  14. if(instance == null)
  15. {
  16. instance = new Singleton();
  17. }
  18.  
  19. return instance;
  20. }
  21. }
  22. }

饿汉式

还没用就已经有实例对象

比如把上面的代码改一改:

  1. class Singleton
  2. {
  3. private Singleton()
  4. {
  5.  
  6. }
  7.  
  8. public static Singleton Instance { get; } = new Singleton();
  9. }

不过同样,这样就不知道到底是时候构造的。

线程不安全/安全

毕竟new一个对象是个动态的过程。步骤还是有点的。如果多个线程访问同一个实例。由于存在共享变量。可能会造成前一个还没好,后面一个有进来的情况。最后有多少线程,就创建多少实例。这样就称为线程不安全。

相反,如果对同一个类不会造成影响。那么就是安全的。

第一个代码片段是不安全的。第二个代码片段是安全的(在线程还没出现之前就已经实例化了,因此饿汉式线程一定是安全的)。

懒汉式 线程安全

因为我们还是怕共享变量的。所以加锁了。

  1. class Singleton
  2. {
  3. private static Singleton instance;
  4. private readonly static object lockobj = new object();
  5. private Singleton()
  6. {
  7.  
  8. }
  9.  
  10. public static Singleton Instance
  11. {
  12. get
  13. {
  14. lock (lockobj)
  15. {
  16. if (instance == null)
  17. {
  18. instance = new Singleton();
  19. }
  20. }
  21.  
  22. return instance;
  23. }
  24. }
  25. }

但每次都加锁,肯定很慢的啦。于是,打算只有第一次创建的时候加锁。

  1. class Singleton
  2. {
  3. private static Singleton instance;
  4. private readonly static object lockobj = new object();
  5. private Singleton()
  6. {
  7.  
  8. }
  9.  
  10. public static Singleton Instance
  11. {
  12. get
  13. {
  14. if(instance == null)
  15. {
  16. lock (lockobj)
  17. {
  18. if (instance == null)
  19. {
  20. instance = new Singleton();
  21. }
  22. }
  23. }
  24.  
  25. return instance;
  26. }
  27. }
  28. }

如果还是怕不知道什么时候构建。可以使用内部类。保证一下

  1. public class Singleton
  2. {
  3. class Nested
  4. {
  5. internal static readonly Singleton instance = new Singleton();
  6. }
  7. private Singleton() { }
  8. public static Singleton Instance { get { return Nested.instance; } }
  9. }

实现单例基类

最后一个是看别人的。

  1. public abstract class Singleton<T> where T : class
  2. {
  3. class Nested
  4. {
  5. // 创建模板类实例,参数2设为true表示支持私有构造函数
  6. internal static readonly T instance = Activator.CreateInstance(typeof(T), true) as T;
  7. }
  8. private static T instance = null;
  9. public static T Instance { get { return Nested.instance; } }
  10. }
  11.  
  12. class TestSingleton : Singleton<TestSingleton>
  13. {
  14. // 将构造函数私有化,防止外部通过new创建
  15. private TestSingleton() { }
  16. }

C# 单例类的更多相关文章

  1. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

  2. iOS中编写单例类的心得

    单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...

  3. 如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

  4. 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类

    static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...

  5. 设计模式(java) 单例模式 单例类

    ·单例类 单实例类,就是这个类只能创建一个对象,保证了对象实例的唯一性. 1.单例模式( Singleton Pattern) 是一个比较简单的模式, 其定义如下:Ensure a class has ...

  6. [转]单例模式——C++实现自动释放单例类的实例

    [转]单例模式——C++实现自动释放单例类的实例 http://www.cnblogs.com/wxxweb/archive/2011/04/15/2017088.html http://blog.s ...

  7. iOS - OC SingleClass 单例类

    前言 单例对象能够被整个程序所操作.对于一个单例类,无论初始化单例对象多少次,也只能有一个单例对象存在,并且该对象是全局的,能够被整个系统访问到. 特点: 在内存中只有一个实例 提供一个全局的访问点 ...

  8. iOS - Swift SingleClass 单例类

    前言 单例对象能够被整个程序所操作.对于一个单例类,无论初始化单例对象多少次,也只能有一个单例对象存在,并且该对象是全局的,能够被整个系统访问到. 单例类的创建 1.1 单例类的创建 1 单例类的创建 ...

  9. Java单例类的简单实现

    对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...

  10. (七)boost库之单例类

    (七)boost库之单例类 一.boost.serialzation的单件实现 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一 ...

随机推荐

  1. day38 14-Spring的Bean的属性的注入:集合属性的注入

    集合:List.Set.Map. package cn.itcast.spring3.demo6; import java.util.List; import java.util.Map; impor ...

  2. python findall函数

  3. NOIP模拟 7.04

    魔术球问题弱化版(ball.c/.cpp/.pas) [题目描述] 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. ( ...

  4. Liferay 7 module项目的依赖问题

    build.gradle中的dependencies和bnd.bnd的Private-Package的关系是,build.gradle解决编译时候所需的所有依赖问题,但是这些依赖并不会被打包到buil ...

  5. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十九章:法线贴图

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十九章:法线贴图 学习目标 理解为什么需要法线贴图: 学习法线贴图如 ...

  6. LeetCode21 Merge Two Sorted Lists

    题意: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ...

  7. 【JZOJ4859】【NOIP2016提高A组集训第7场11.4】连锁店

    题目描述 Dpstr开了个饮料连锁店,连锁店共有n家,出售的饮料种类相同.为了促销,Dpstr决定让每家连锁店开展赠送活动.具体来说,在第i家店,顾客可以用ai个饮料瓶兑换到bi瓶饮料和1个纪念币(注 ...

  8. weixin 微信开放平台 微信公众平台

    官网地址入口 微信小程序 https://mp.weixin.qq.com/ appid and openid not match 1.appid :是公众号的ID. 2.openid:关注公众号生成 ...

  9. H5+ 重写在线升级版本比较代码

    重写h5+在线升级版本比较代码 hello h5+版本在线升级提供了如下的版本比较方法,逻辑比较繁琐,相关判断多余,非常不宜读. 先判断新旧版本有无, 接着分割为数组比较数组项大小,而且还只取了前四项 ...

  10. ssh scp nc

    ssh远程连接 ssh root@192.168.111.11 scp数据传输,(secure copy) 1.下载.拉取 scp root@192.168.111.11:/root/database ...