单例类

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

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

需要了解的术语

懒汉式

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

比如:

class Singleton
{
private static Singleton instance = null; private Singleton()
{ } public static Singleton Instance
{
get
{
if(instance == null)
{
instance = new Singleton();
} return instance;
}
}
}

饿汉式

还没用就已经有实例对象

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

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

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

线程不安全/安全

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

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

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

懒汉式 线程安全

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

class Singleton
{
private static Singleton instance;
private readonly static object lockobj = new object();
private Singleton()
{ } public static Singleton Instance
{
get
{
lock (lockobj)
{
if (instance == null)
{
instance = new Singleton();
}
} return instance;
}
}
}

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

class Singleton
{
private static Singleton instance;
private readonly static object lockobj = new object();
private Singleton()
{ } public static Singleton Instance
{
get
{
if(instance == null)
{
lock (lockobj)
{
if (instance == null)
{
instance = new Singleton();
}
}
} return instance;
}
}
}

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

public class Singleton
{
class Nested
{
internal static readonly Singleton instance = new Singleton();
}
private Singleton() { }
public static Singleton Instance { get { return Nested.instance; } }
}

实现单例基类

最后一个是看别人的。

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

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. 时间模块(import time)

    时间戳时间: float数据类型,给机器用的 print(time.time()) =>1533713657.5423343 结构化时间: 上下两种格式的中间状态 能够通过属性名来获取对象中的值 ...

  2. startActivity 流程图

  3. 链表源代码(C语言实现)

    源代码(C语言实现) ①.构造链表节点 typedef struct Node    //一个单独的节点                   {                         int ...

  4. GenericServlet vs HttpServlet

     1>>>>>>>> Difference between HttpServlet vs Generic Severlet javax.servlet. ...

  5. Spark-day01

      Spark初始 什么是Spark Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室) ...

  6. C++:static类

    static自我理解 static使得数据成员或者函数生命周期为整个文件所在程序的生命周期, 在C中还可以用它避免被其它文件使用为外部成员 static类 明确:类的静态数据成员它被所有类对象共享,但 ...

  7. Directx11教程(54) 简单的基于GS的billboard实现

    原文:Directx11教程(54) 简单的基于GS的billboard实现     本章我们用一个billboard的实现来学习D3D11中的GS.     在VS shader中,我们输入的是顶点 ...

  8. python 利用csv模块导入数据

  9. Linux下的python安装

    centos7安装python3 以及tab补全功能   1.安装python3 1.1下载python源码包 网址:https://www.python.org/downloads/release/ ...

  10. HZOJ 导弹袭击

    比较显然的一个性质是如果存在$a(i)>=a(j) \& \& b(i)>=b(j)$那么j没用. 我们并不需要A,B的具体取值,我们之关心$\frac {A}{B}$. ...