前言

  设计模式的文章很多,所以此文章只是为了巩固一下自己的基础,说的不详细请见谅。

 介绍 - 单例模式

  官方定义:确保一个类只有一个实例,并提供一个全局访问点。

  通俗定义:就是一个类只有一个单个实例。(也没啥区别)

 实现

  如何保证一个类只有一个实例呢?

  1. 首先一个类是如何创建实例的? - 通过构造函数

  2. 如何保证只创建一个呢? - 构造函数只执行一次

  3. 如何保证构造函数只执行一次呢? - 访问外部类无权访问

  4. 如何让访问外部类无权访问? - 私有方法

  问题解决,上代码:

    /// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}

测试输出 HashCode :

  class Program
{
static void Main(string[] args)
{
Singleton.Instance.WriteLine();
Singleton.Instance.WriteLine();
Singleton.Instance.WriteLine();
Console.Read();
}
}

结果:

这样就结束了吗? -(身为C#老鸟的我还要考虑下线程安全的问题,考虑并发的情况)

我们需要构建一个并发的情形及多条线程同时创建对象,下面我就用简单粗暴的方法,需要对单例进行修改:

        /// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
return _instance;
}
}

调用测试:

class Program
{
static void Main(string[] args)
{
//线程1
Thread thread1 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
//线程2
Thread thread2 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
//线程3
Thread thread3 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
thread1.Start();
thread2.Start();
thread3.Start();
Console.Read();
}
}

输出结果:

所以我们要对代码进行改进(加锁):

/// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 锁
/// </summary>
private static object locker = new object();
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
lock (locker)
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
}
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}

测试结果:

解决!

锁是个好东西但是要慎用,它是很耗资源的。所以还需要对代码进行改进,看代码我们知道只有 _instance 为 null 时才需要考虑并发加锁,所以我们再次改进:

    /// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 锁
/// </summary>
private static object locker = new object();
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if(_instance == null)
{
lock (locker)
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
}
}
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}

欢迎批评指正!转载请注明出处:http://www.cnblogs.com/xinwang/p/6294784.html

C# 设计模式巩固 - 单例模式的更多相关文章

  1. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

  2. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  4. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  5. 设计模式之单例模式的简单demo

    /* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...

  6. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  7. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

  8. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

随机推荐

  1. SecureCRT 7在ubuntu下的破解方法

    主要破解方法: http://www.boll.me/archives/599 http://www.boll.me/archives/680

  2. leveldb0

    leveldb的源代码进行学习,则纯粹是出于一个码农对美好世界进行探究的好奇.接下来将尽可能从源代码上给出leveldb代码的详尽注释,这里先列出自己在阅读前后的主要参考. 0 官方文档http:// ...

  3. 【转】网页窗口DIV自定义拖动

    一个来自网上的东西- -被我捡到了 然后我访问到了 发出来就可以粘贴复制自己做成js文件了吧 // by zhangxinxu welcome to visit my personal website ...

  4. 条件编译#ifdef的妙用详解

    c语言中条件编译相关的预编译指令,包括  #define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define           ...

  5. 20145321 《Java程序设计》第10周学习总结

    20145321 <Java程序设计>第10周学习总结 教材学习内容总结  网络编程:网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. IP地址:为了能够方便的识别网络上 ...

  6. 20145231熊梓宏 《网络对抗》 Bof逆向基础.shellcode注入

    20145231网络对抗<逆向及Bof基础>shellcode注入 实验目的与要求 1.本次实践的对象是一个名为pwn1的linux可执行文件. 2.若该程序正常执行,则main函数会调用 ...

  7. JS时间和字符串的相互转换 Date+String

    1.js字符串转换成时间 1.1方法一:输入的时间格式为yyyy-MM-dd function convertDateFromString(dateString) { if (dateString) ...

  8. Xcode8编辑代码崩溃解决办法

    更新了Xcode8带来了一系列问题,最大的困扰就是不支持插件了,而且最关键的是一敲代码就崩溃(就是写一个字母就开始崩),在网上找了很多解决,发现是之前装的插件遗留下来的问题,将插件全部删掉就解决了,下 ...

  9. 编程之美——求1~N的整数中1的个数

    为了依次求个位,十位,百位中1的个数,我们可以把这个数字分为三部分,高位数字,当前位数字,低位数字. 如果当前位为0,那么此位为1的数目与高位数字有关 如果当前位为1,那么此位为1的数目与高位和地位都 ...

  10. SQLite-C#-帮助类

    public static class SQLiteHelper { private static string connectionString = string.Empty; #region vo ...