温故而知新:设计模式之单件模式(Singleton)

 1 using System;
 2 
 3 namespace Singleton
 4 {
 5  class Program
 6     {
 7  static void Main(string[] args)
 8         {
 9             Singleton s1 = Singleton.Instance;
10             Singleton s2 = Singleton.Instance;
11 
12             Console.WriteLine(object.ReferenceEquals(s1, s2));
13 
14             Console.Read();
15         }
16     }
17 
18 
19 
20  //线程安全的单件写法
21  sealed class Singleton //sealed并非必要,看需求而定
22     {
23  private Singleton() { }//私有构架器的目的是为了防止编译器自动创建默认的公用构架器(从而阻止了用户new类的实例)
24 
25  private static volatile Singleton _instance;//valatile关键字用于声明该代码不会被编译器自动优化,从而更严格的保证了单件的实现
26 
27  private static object _lockHelper = new object();//同步锁辅助对象
28 
29  //定义一个只读实例属性
30  public static Singleton Instance
31         {
32  get
33             {
34  if (_instance == null) //初次检测,以防止多次创建实例
35                 {
36  //#1
37  lock (_lockHelper) //多线程环境下,极有可能多个线程“同时”运行到这里,所以如果不用同步锁,有可能会出现多个线程“同时”创建多个实例
38                     {
39  if (_instance == null) //二次检查以防止创建多个实例(解释:如果不加此句,假设有二个线程同时进入#1处,第一个线程锁定-->创建实例-->解锁 到达#2处,第二个线程还留在#1处,同样还是会创建第二个实例,换言之:加锁的目的是为了防止多个线程同时创建,让线程强制有先后顺序,然后用二次检查来防止重复创建
40                         {
41                             _instance = new Singleton();
42                         }
43                     }
44  //#2
45                 }
46  return _instance;
47             }
48         }
49     }
50 
51 
52  #region //这是c#语言中特有的优雅实现方式
53  //sealed class Singleton //sealed并非必要,看需求而定
54  //{
55  //    public static readonly Singleton Instance = new Singleton();
56 
57  //    private Singleton() { }
58  //}
59 
60  //上面的代码等同于
61 
62  //sealed class Singleton 
63  //{
64  //    public static readonly Singleton Instance; //因为静态属性初始化后,仍然有可能被赋值修改,所以必须加上readonly以保证单件实例不再被修改的初衷
65 
66  //    static Singleton() //静态构造器,会在静态成员初次访问前被调用,同时编译器会自动给静态构造器加锁/解锁,所以该方法同样适合于多线程(线程安全)
67  //    {
68  //        Instance = new Singleton();
69  //    }
70 
71  //    private Singleton() { }
72  //}
73  #endregion
74 }
75 

 Singleton的精髓在于:对于类的实例个数做了限制,只要领会了这一点,可以应用到很多场景,比如聊天室最多只能让100个人进来,数据库连接实例只能有200个...

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏chenssy

【死磕Java并发】-----Java内存模型之从JMM角度分析DCL

DCL,即Double Check Lock,即双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么会...

13830
来自专栏行者悟空

Hadoop之MapReduce原理及运行机制

21940
来自专栏听雨堂

Python防止sql注入

看了网上文章,说的都挺好的,给cursor.execute传递格式串和参数,就能防止注入,但是我写了代码,却死活跑不通,怀疑自己用了一个假的python 最后,...

40770
来自专栏帘卷西风的专栏

关于mysql自增id的获取和重置

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

54420
来自专栏运维一切

模拟linux内存管理代码 转

这个代码模拟实现了linux内存管理的三个算法ff、wf、bf。这三个算法都是连续分配的方式,这种方式的缺点就是内存碎片很难被再次利用。

9510
来自专栏技术点滴

单例模式(Singleton)

单例模式(Singleton) 单例模式(Singleton) 意图:保证一个类只有一个实例,并提供一个访问它的全局访问点。 应用:Session或者控件的唯一...

19960
来自专栏专注 Java 基础分享

初识Hibernate之关联映射(一)

     上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作。但这都是基于单张表的操作,如果两张或者两张以上的表之间存在...

19480
来自专栏osc同步分享-java技术分享站

mybatis 的一些常用功能

1. association 查询结果的一对一关联: <resultMap id="blogResult" type="Blog"> <id propert...

29680
来自专栏芋道源码1024

数据库中间件 MyCAT 源码解析 —— 分片结果合并(一)

1. 概述 相信很多同学看过 MySQL 各种优化的文章,里面 99% 会提到:单表数据量大了,需要进行分片(水平拆分 or 垂直拆分)。分片之后,业务上必然面...

474130
来自专栏Java成长之路

单例模式

所谓饿汉式单例设计模式,就是将类的静态实例作为该类的一个成员变量,也就是说在JVM 加载它的时候就已经创建了该类的实例,因此它不会存在多线程的安全问题。

11330

扫码关注云+社区

领取腾讯云代金券