1、简单实现

 
 
 
 
 

C#

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public sealed class Singleton
    {
        static Singleton instance = null;
 
        public void Show()
        {
            Console.WriteLine(  "instance function");
        }
        private Singleton()
        {
        }
 
        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }

评注:
对于线程来说不安全
单线程中已满足要求

优点:
由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能
直到对象要求产生一个实例才执行实例化;这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的 singleton。

2、线程的安全

 
 
 
 
 

C#

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public sealed class Singleton
    {
        static Singleton instance = null;
        private static readonly object padlock = new object();
 
        private Singleton()
        {
        }
 
        public static Singleton Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
 
                return instance;
            }
        }
    }

评注:
同一个时刻加了锁的那部分程序只有一个线程可以进入
对象实例由最先进入的那个线程创建
后来的线程在进入时(instence == null)为假,不会再去创建对象实例
增加了额外的开销,损失了性能

3、双重锁定

 
 
 
 
 

C#

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public sealed class Singleton
    {
        static Singleton instance = null;
        private static readonly object padlock = new object();
 
        private Singleton()
        {
        }
 
        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

评注:
多线程安全
线程不是每次都加锁
允许实例化延迟到第一次访问对象时发生

4、静态初始化

 
 
 
 
 

C#

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public sealed class Singleton
    {
        private static readonly Singleton instance = null;
        static Singleton()
        {
            instance = new Singleton();
        }
        private Singleton()
        {
        }
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
    }

评注:
依赖公共语言运行库负责处理变量初始化
公共静态属性为访问实例提供了一个全局访问点
对实例化机制的控制权较少(.NET代为实现)
静态初始化是在 .NET 中实现 Singleton 的首选方法

小注:
静态构造函数既没有访问修饰符,C#会自动把他们标记为private,之所以必须标记为private,是为了阻止开发人员写的代码调用它,对它的调用总是由CLR负责的。

5、延迟初始化

 
 
 
 
 

C#

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public sealed class Singleton
    {
        private Singleton()
        {
        }
        public static Singleton Instance
        {
            get
            {
                return Nested.instance;
            }
        }
 
        public static void Hello()
        {
        }
 
        private class Nested
        {
            internal static readonly Singleton instance = null;
            static Nested()
            {
                instance = new Singleton();
            }
        }
    }

评注:
初始化工作由Nested类的一个静态成员来完成,这样就实现了延迟初始化。

由于静态函数的调用时机,是在类被实例化或者静态成员被调用的时候进行调用,并且是由.net框架来调用静态构造函数来初始化静态成员变量,所以,如果按照写法四来写,再调用Hello方法的时候,就会实例化出来Singleton实例,这不是我们想看到的,因为我们有可能只是想用Hello方法,而不是别的。

注意事项:
1、Singleton模式中的实例构造器可以设置为protected以允许子类派生。
2、Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
3、Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。
4、Singletom模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。

总结:
1、Singleton模式是限制而不是改进类的创建。
2、理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的构造器的任意调用”。
3、可以很简单的修改一个Singleton,使它有少数几个实例,这样做是允许的而且是有意义的。

C# 单例模式的五种写法的更多相关文章

  1. 单例模式的N种写法

    单例模式算是设计模式中最容易理解,也是最容易手写代码的模式了吧.但是其中的坑却不少,所以也常作为面试题来考.本文主要对几种单例写法的整理,并分析其优缺点.很多都是一些老生常谈的问题,但如果你不知道如何 ...

  2. Java:单例模式的七种写法(转载)

    第一种(懒汉,线程不安全): package Singleton; /** * @echo 2013-10-10 懒汉 线程不安全 */ public class Singleton1 { priva ...

  3. Java:单例模式的七种写法[转]

    第一种(懒汉,线程不安全):  1 public class Singleton {   2     private static Singleton instance;   3     privat ...

  4. 【JAVA学习】单例模式的七种写法

    尊重版权:http://cantellow.iteye.com/blog/838473 第一种(懒汉.线程不安全): Java代码   public class Singleton { private ...

  5. KandQ:单例模式的七种写法及其相关问题解析

    设计模式中的单例模式可以有7种写法,这7种写法有各自的优点和缺点: 代码示例(java)及其分析如下: 一.懒汉式 public class Singleton { private static Si ...

  6. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...

  7. Java:单例模式的七种写法<转>

    第一种(懒汉,线程不安全):  1 public class Singleton {   2     private static Singleton instance;   3     privat ...

  8. Java 单例模式的七种写法

    Java 单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Sin ...

  9. 温故而知新(java实现)单例模式的七种写法

    第一种(懒汉,线程不安全): Java代码 public class Singleton { private static Singleton instance; private Singleton ...

随机推荐

  1. php打印错误报告

    //error handler functionfunction customError($errno, $errstr){ echo "<b>Error:</b> ...

  2. vue-cli 配置 proxyTable pathRewrite

    vue-config-index.js中,proxyTable中的pathRewrite有什么用呢? 首先,在ProxyTable模块中设置了‘/api’,target中设置服务器地址,也就是接口的开 ...

  3. YouTube Cobalt 浏览器支持

    Cobalt介绍: Cobalt浏览器是YouTube公司定制的一款专用浏览器,Cobalt的使命,是在电视机端,使用灵活多变web形式实现流畅的交互操作,从而替代Android,与普通浏览器不同,C ...

  4. 设置获取cookie,setCookie,getCookie

    设置cookie: function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getT ...

  5. python3与python2的区别(目前遇到的)

    1.进击的print,变成一个函数,print() 2.urllib大一统,呵呵 3.python3默认绝对路径导入

  6. 用Jenkins自动化搭建测试环境-前奏

    用Jenkins自动化搭建测试环境-前奏 1.安装 参考及启动:https://www.cnblogs.com/Eric15/articles/9828062.html 2.插件 新手一般按推荐安装即 ...

  7. Mapped Statements collection already contains value for*

    检查了一下,没有重复的,参数也都正确,把报错的地方注释掉继续报下一个方法错误.重启也无效 最后发现,最后一个方法的返回值类型resultType="java.util.Map"写成 ...

  8. mysql 5.6 datetime 保存精确到秒

    mysql中的CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP 设置默认值 now(3)  datetime 长度  3   保存精确到秒

  9. ABAP中不修改内表参照的结构,给内表/结构体增加字段

    Situation: DATA:       itab  TYPE STANDARD TABLE OF zsrsodtla_stru1,      wa_itab TYPE zsrsodtla_str ...

  10. day 11 生成器

    生成器生成器本质就是迭代器,生成器是自己用python代码写的迭代器 将函数变成生成器yield用next 取值一个next,对应一个yield def func(): yield 111 yield ...