前言

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

 介绍 - 单例模式

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

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

 实现

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

  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. UVALive - 7740 Coding Contest 2016 青岛区域赛 (费用流)

    题意:每个点i有\(s_i\)个人和\(b_i\)份食物,每个人都要找到一份食物.现在有M条有向边,从点i到点j,容量为c,第一次走过不要紧,从第二次开始就要承担\(p(0<p<1)\)的 ...

  2. Linux中find

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...

  3. 好用的http client库CPP REST SDK

    前言 C++中http client库本身就少,好用的就更少了,在了解微软开源的CPP REST SDK库之前,我知道的C++ http client库有libcurl(这个是C语言的),Qt的QNe ...

  4. 通过paramiko模块在远程主机上执行命令

    安装paramiko模块 /usr/local/python36/bin/pip3 install paramiko 1.获取cpu使用率 #!/usr/bin/python #coding=utf8 ...

  5. [翻译]解读CSS中的长度单位

    测量,在WEB设计上是非常重要的.在CSS中有至少10种不同的测量单位.每种单位都有其独特的作用,使用它们,可以使页面,在各种设备上,很好的工作.一旦你熟悉了所有这些单位,你可以更准确地设定元素的大小 ...

  6. SpringBoot 打包为Docker进行

    可以有两种方式: 1.dockerfile 2.maven docker 第一种方式:通过dockerfile打包Docker镜像 1.将dockerfile和 springboot打包的jar文件放 ...

  7. JAVA基础补漏--泛型通配符

    泛型通配符只能用于方法的参数 不能用对象定义 public class Test { public static void main(String[] args) { ArrayList<Str ...

  8. 从0开始 Java学习 packet用法

    packet 包的用法 参考博客:https://www.cnblogs.com/Ring1981/p/6240412.html 用法 java 源文件带有包名,往往容易出错 如:H:\code\He ...

  9. python print和strip

    在使用这两个模块时犯过错误,总结如下: 1.print print在打印时会自动加上换行,例如: >>> for i in xrange(1,5): ... print i ... ...

  10. Codeforces Round #414 C. Naming Company

    http://codeforces.com/contest/794/problem/C 题意: 有两个人要为公司起名字,每个人手中都有n个字符,现在要取一个n个字符长度的公司名.两人轮流取名,每次选择 ...