经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
单例模式的实现
来源:cnblogs  作者:SH高山流水  时间:2021/1/25 11:14:06  对本文有异议

  记一下学习单例模式的笔记:

  单例就是要保证该类仅有一个实例。实现完全封闭的单例(外部不能new)其实就要两点要求:

  1. 全局访问:需要一个该类型的全局静态变量,每次获取实例时都要判断它是否null,不存在new,存在通过一个方法直接返回该值获取实例来保证对象唯一;
  2. 实例化控制:new实例不能外部new、造成实例不唯一,需要一个私有构造器禁用共有构造器。

  根据new实例的时机,分为饿汉式和懒汉式:

一、 饿汉式单例:静态变量初始化时new

  特点:加载时new,一开始全局就存在该唯一实例,每次用到只要获取就行,提前占用系统资源但不存在线程安全问题。代码如下:

  1. 1 public sealed class Singleton
  2. 2 {
  3. 3 private static readonly Singleton instance = new Singleton();
  4. 4 private Singleton() { }
  5. 5
  6. 6 public static Singleton GetInstance()
  7. 7 {
  8. 8 return instance;
  9. 9 }
  10. 10 }
View Code

二、 懒汉式单例:需要该实例的时候再new

  特点:真正需要用到的时候才实例化,不提前占用资源但多个线程同时用到该实例时,会存在判断静态变量都为null都去new而产生多个实例的情况。有线程安全问题,但可以用双重锁定解决。

  单线程懒汉单例代码如下:

  1. 1 public class Singleton
  2. 2 {
  3. 3 private static Singleton instance = null;
  4. 4 private Singleton() { }
  5. 5
  6. 6 public static Singleton GetInstance()
  7. 7 {
  8. 8 if (instance == null)
  9. 9 instance = new Singleton();
  10. 10 return instance;
  11. 11 }
  12. 12 }
View Code

  多线程懒汉单例代码如下:

  1. 1 public class Singleton
  2. 2 {
  3. 3 private static Singleton instance = null;
  4. 4 private static readonly object obj = new object();
  5. 5 private Singleton() { }
  6. 6
  7. 7 public static Singleton GetInstance()
  8. 8 {
  9. 9 //双重锁定
  10. 10 if (instance == null)//只有为null需要实例化处理时才进行加锁,提高性能避免不必要的等待
  11. 11 {
  12. 12 lock (obj)
  13. 13 {
  14. 14 if (instance == null)//避免其他线程等待锁释放期间有线程已经实例化,从而造成多个实例
  15. 15 instance = new Singleton();
  16. 16 }
  17. 17 }
  18. 18 return instance;
  19. 19 }
  20. 20 }
View Code

三、 注册式单例

  介绍一个有意思的单例-泛型注册式,是对单例的扩展,主要了解它的设计思想。

  其实每个类单例模式实现代码都是差不多的:

  1. 相同结构和成员(字段、属性、行为等):是否可以考虑进行抽象提取一个公共的调用接口?
  2. 成员类型或输入输出类型不是固定的:是否可以考虑设计一个适用于不同类型的通用处理方式?这个适用不同类型通用解决就要用到泛型。

  实现代码如下(例子使用饿汉式,当然也可以用懒汉式):

  1. 1 public abstract class Singleton<T> where T:class,new()
  2. 2 {
  3. 3 private static readonly T instance = new T();
  4. 4 protected Singleton() { }
  5. 5
  6. 6 public static T GetSingleton()//获取单例
  7. 7 {
  8. 8 return instance;
  9. 9 }
  10. 10 }
  11. 11 public class Person : Singleton<Person> { }
View Code

  可以看到这种单例通过继承的方式,既可以new实例也可以获取单例实例。如果要实现上面的完全封闭(禁用外部new),也可以完全在Person类中写个私有构造器在Singleton<T>类中实例的获取new T()改为反射调用私有构造器的方式实现,总感觉怪怪的。

  下面是主程序调用该单例方法:

  1. 1 static void Main(string[] args)
  2. 2 {
  3. 3 Person p1 = Person.GetSingleton();
  4. 4 Person p2 = Singleton<Person>.GetSingleton();
  5. 5
  6. 6 if (object.ReferenceEquals(p1, p2))
  7. 7 {
  8. 8 Console.WriteLine("两个对象是同一实例");
  9. 9 }
  10. 10 Console.ReadKey();
  11. 11 }
  12. 12
View Code

  输出结果:

  

原文链接:http://www.cnblogs.com/jn-shao/p/14318813.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号