博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-单件模式
阅读量:4877 次
发布时间:2019-06-11

本文共 1613 字,大约阅读时间需要 5 分钟。

1经典模式

    class Singleton

    {

        static Singleton instance;

        Singleton() { }

        public static Singleton Instance//静态属性?

        {

            get {

                if (instance == null)

                    instance = new Singleton();

                return instance;

            }

        }

    }

该类构造函数被定义为private,静态属性Instance是客户程序获得类型实例的唯一入口。if语句控制实例创建的数量。该方式在多线程环境下存在缺陷。当多个线程几乎同时调用该类的Instance属性方法时,Instance成员可能还没被实例化,故它可能被不同线程创建了多次,各个线程引用了不同的实例。

2改进 double check方式

    class Singleton

    {

        static volatile Singleton instance;

        Singleton() { }

        public static Singleton Instance

        {

            get {

                if (instance == null)

                    lock (typeof(Singleton))

                    {

                        if(instance == null)

                        instance = new Singleton();

                    }

                   

                return instance;

            }

        }

    }

说明:

1)  如果没有外层if,客户程序每次执行时都先lock住Singleton类型,但在绝大多数情况下,每次都锁定Singleton类型效率太差。

2)  lock加内层if构成了一个相对安全的实例构造环境。

3)  一旦唯一的实例被创建后,后续新发起的调用无须经lock部分,直接在外层if判断后就可获得既有的唯一实例引用。

4)  volatile关键字表示字段可能被多个线程修改。声明为volatile的字段不受编译器优化(一般默认的编译优化假定由单个线程访问)的限制,这样可以确保该字段在任何时间都呈现的是最新的值,即在被lock后,如果还没真正完成new Singleton(),新加入的线程看到的instance都是Null.

问题:构造过程为什么不放到静态构造函数中呢?

3多线程环境下实现单件模式的方式

    class Singleton

    {

        Singleton() { }

        public static readonly Singleton Instance = new Singleton();

}

说明

1)    Instance是类的公共静态成员,故它会在类第一次被用到的时候构造出来。这样就不用把它的构造语句显示写在静态构造函数中。是因为对其进行了初始化了吗?

2)    此单件模式是线程安全的

4

       public class Spooler   {

              static bool instance_flag = false; //true if one instance

              public Spooler()  {

              if (instance_flag)

                     throw new SingletonException("Only one printer allowed");

              else

                     instance_flag=true;     //set flag for one instance

              Console.WriteLine ("printer opened");

          }

       }

 

5需注意的地方

1)              不要实现ICloneable接口或继承自其相关的子类,否则客户程序可以跳过已经隐蔽起来的类构造函数。

2)              严防序列化。不能对期望具有Singleton特性的类型声明SerializableAttribute属性。

转载于:https://www.cnblogs.com/chengzhang-cyx/archive/2012/06/09/2542873.html

你可能感兴趣的文章
一道php笔试题
查看>>
4.标准体重: 男士体重=身高-100±3 女士体重=身高-110±3 输入性别、身高、体重,查看体重是否标准...
查看>>
UVA748 Exponentiation 解题报告
查看>>
hud 4454 Stealing a Cake 解题报告
查看>>
冒泡排序
查看>>
深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)
查看>>
hdu_3518_Boring counting(后缀数组)
查看>>
逆波兰表达式计算'1 + (5 - 2) * 3'
查看>>
【洛谷2051】[AHOI2009] 中国象棋(烦人的动态规划)
查看>>
常见渗透测试工具集成系统简介
查看>>
Cannot run Eclipse; JVM terminated. Exit code=13
查看>>
文件上传
查看>>
敏捷软件开发_UML<一>
查看>>
Coursera台大机器学习技法课程笔记07-Blending and Bagging
查看>>
(五)函数装饰器和闭包
查看>>
经典变量练习
查看>>
SQL注入学习总结(四):SQL注入中的绕过
查看>>
Ajax笔记
查看>>
Nginx配置文件详细说明
查看>>
python遇到的问题汇总
查看>>