知识大全 Singleton设计模式的C#实现

Posted

篇首语:不学习历史的人注定要重复错误。——丘吉尔本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Singleton设计模式的C#实现相关的知识,希望对你有一定的参考价值。

Singleton设计模式的C#实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

Singleton模式    Singleton(译为单件或单态)模式是设计模式中比较简单而常用的模式    有些时候在整个应用程序中 会要求某个类有且只有一个实例 这个时候可以采用Singleton模式进行设计 用Singleton模式设计的类不仅能保证在应用中只有一个实例 而且提供了一种非全局变量的方法进行全局访问 称为全局访问点 这样对于没有全局变量概念的纯面向对象语言来说是非常方便的 比如C#    本文用一个计数器的例子来描述在C#中如何使用Singleton模式 计数的值设计为计数器类的一个私有成员变量 它被 个不同的线程进行读写操作 为保证计数的正确性 在整个应用当中必然要求计数器类的实例是唯一的 Singleton的实现方式    首先看看教科书方式的Singleton标准实现的两种方法 以下用的是类C#伪代码    方法一 using System; namespace csPattern Singleton public class Singleton static Singleton uniSingleton = new Singleton(); private Singleton() static public Singleton instance() return uniSingleton; 方法二 using System; namespace csPattern Singleton public class Singleton static Singleton uniSingleton; private Singleton() static public Singleton instance() if (null == uniSingleton) uniSingleton = new Singleton _lazy(); return uniSingleton;   Singleton模式的实现有两个技巧 一是使用静态成员变量保存 全局 的实例 确保了唯一性 使用静态的成员方法instance() 代替 new关键字来获取该类的实例 达到全局可见的效果 二是将构造方法设置成为private 如果使用new关键字创建类的实例 则编译报错 以防编程时候笔误     上面方法二的初始化方式称为lazy initialization 是在第一次需要实例的时候才创建类的实例 与方法一中类的实例不管用不用一直都有相比 方法二更加节省系统资源 但是方法二在多线程应用中有时会出现多个实例化的现象   假设这里有 个线程 主线程和线程 在创建类的实例的时候可能会遇到一些原因阻塞一段时间(比如网络速度或者需要等待某些正在使用的资源的释放) 此时的运行情况如下   主线程首先去调用instance()试图获得类的实例 instance()成员方法判断该类没有创建唯一实例 于是开始创建实例 由于一些因素 主线程不能马上创建成功 而需要等待一些时间 此时线程 也去调用instance()试图获得该类的实例 因为此时实例还未被主线程成功创建 因此线程 又开始创建新实例 结果是两个线程分别创建了两次实例 对于计数器类来说 就会导致计数的值被重置 与Singleton的初衷违背 解决这个问题的办法是同步    下面看看本文的计数器的例子的实现    使用方法一 using System; using System Threading; namespace csPattern Singleton public class Counter static Counter uniCounter = new Counter(); //存储唯一的实例 private int totNum = ; //存储计数值 private Counter() Thread Sleep( ); //这里假设因为某种因素而耽搁了 毫秒 //在非lazy initialization 的情况下 不会影响到计数 static public Counter instance() return uniCounter; public void Inc() totNum ++; //计数加 public int GetCounter() return totNum; //获得当前计数值   以下是调用Counter类的客户程序 在这里我们定义了四个线程同时使用计数器 每个线程使用 次 最后得到的正确结果应该是 using System; using System IO; using System Threading; namespace csPattern Singleton MutileThread public class MutileClient public MutileClient() public void DoSomeWork() Counter myCounter = Counter instance(); //方法一 //Counter_lazy myCounter = Counter_lazy instance(); //方法二 for (int i = ; i < ; i++) myCounter Inc(); Console WriteLine( 线程 报告: 当前counter为: Thread CurrentThread Name ToString() myCounter GetCounter() ToString()); public void ClientMain() Thread thread = Thread CurrentThread; thread Name = Thread ; Thread thread =new Thread(new ThreadStart(this DoSomeWork)); thread Name = Thread ; Thread thread =new Thread(new ThreadStart(this DoSomeWork)); thread Name = Thread ; Thread thread =new Thread(new ThreadStart(this DoSomeWork)); thread Name = Thread ; thread Start(); thread Start(); thread Start(); DoSomeWork(); //线程 也只执行和其他线程相同的工作    以下为Main函数 本程序的测试入口 using System; namespace csPattern Singleton public class RunMain public RunMain() static public void Main(string[] args) MutileThread MutileClient myClient = new MutileThread MutileClient(); myClient ClientMain(); System Console ReadLine();    执行结果如下    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    线程Thread 报告: 当前counter为:    由于系统线程调度的不同 每次的执行结果也不同 但是最终结果一定是    方法一中由于实例一开始就被创建 所以instance()方法无需再去判断是否已经存在唯一的实例 而返回该实例 所以不会出现计数器类多次实例化的问题 使用方法二 using System; using System Threading; using System Runtime CompilerServices; namespace csPattern Singleton public class Counter_lazy static Counter_lazy uniCounter; private int totNum = ; private Counter_lazy() Thread Sleep( ); //假设多线程的时候因某种原因阻塞 毫秒 [MethodImpl(MethodImplOptions Synchronized)] //方法的同步属性 static public Counter_lazy instance() if (null == uniCounter) uniCounter = new Counter_lazy(); return uniCounter; public void Inc() totNum ++; public int GetCounter() return totNum;   不知道大家有没有注意到instance()方法上方的[MethodImpl(MethodImplOptions Synchronized)] 语句 他就是同步的要点 他指定了instance()方法同时只能被一个线程使用 这样就避免了线程 调用instance()创建完成实例前线程 就来调用instance()试图获得该实例    根据MSDN的提示 也可以使用lock关键字进行线程的加锁 代码如下 using System; using System Threading; namespace csPattern Singleton public class Counter_lazy static Counter_lazy uniCounter; static object myObject = new object(); private int totNum = ; private Counter_lazy() Thread Sleep( ); //假设多线程的时候因某种原因阻塞 毫秒 static public Counter_lazy instance() lock(myObject) if (null == uniCounter) uniCounter = new Counter_lazy(); return uniCounter; public void Inc() totNum ++; public int GetCounter() return totNum;   lock()是对一个对象加互斥锁 只允许一个线程访问其后大括号中语句块 直到该语句块的代码执行完才解锁 解锁后才允许其他的线程执行其语句块   还可以使用Mutex类进行同步 定义private static Mutex mut = new Mutex();后 修改instance()如下 同样可以得到正确的结果 static public Counter_lazy instance() mut WaitOne(); if (null == uniCounter) uniCounter = new Counter_lazy(); mut ReleaseMutex(); return uniCounter;   注意的是 本例中使用方法二要更改方法一的客户程序 去掉Counter_lazy intance()的注释 并将Counter intance()注释   singleton模式还可以拓展 只要稍加修改 就可以限制在某个应用中只能允许m个实例存在 而且为m个实例提供全局透明的访问方法 cha138/Article/program/net/201311/12545

相关参考

知识大全 从C#的Singleton设计模式实现看.NETFramework特性对开发者的重要性

从C#的Singleton设计模式实现看.NETFramework特性对开发者的重要性  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布

知识大全 Singleton模式

最简单的设计模式学习:Singleton模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  学习

知识大全 设计模式之Singleton(单态模式)

设计模式之Singleton(单态模式)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要讨论

知识大全 在Java中应用设计模式Singleton

在Java中应用设计模式Singleton  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  &nb

知识大全 单件模式singleton的理解

  Singleton模式是一个较为简单的模式下面的代码就可以建立一个Singlton模式的例子这是一个写系统日志的类实际应用的意义在于在内存中只保存一个实例避免开辟多个功能相同的工具类实例而耗用系统

知识大全 在Java中应用设计模式之Singleton

在Java中应用设计模式之Singleton  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  基本

知识大全 23种设计模式的Java版--Singleton(单例)

23种设计模式的Java版--Singleton(单例)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 .Net 单例模式(Singleton)

.Net单例模式(Singleton)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!单例模式的意思

知识大全 C#设计模式编程之抽象工厂模式

C#设计模式编程之抽象工厂模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  抽象工厂(Abst

知识大全 C#中的Adapter设计模式浅析

C#中的Adapter设计模式浅析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  意图  把一个