• 设计模式详解:单例模式


    本篇来看一下创建型模式中最常用的第三种模式:单例模式。仍然是先看两张图,复习模式类型,加深记忆。

    定义:

    单例模式:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例

    Singleton Pattern: Ensure a class has only one instance, and provide a global point of access to it.

    要点:

    某个类只能有一个实例

    必须自行创建这个实例

    必须自行向整个系统提供这个实例

    最简单的实用案例就是windows操作系统中的任务管理器,还有负载均衡的唯一性等。

    结构:

    分类:

    饿汉式单例类:无须考虑多个线程同时访问的问题;调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长

    1. class EagerSingleton
    2. {
    3. private static EagerSingleton instance = new EagerSingleton();
    4. private EagerSingleton() { }
    5. public static EagerSingleton GetInstance()
    6. {
    7. return instance;
    8. }
    9. }

    懒汉式单例类:实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能受到一定影响

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

    懒汉式防止不同进程重复调用,可以双重检查锁定:

    1. class LazySingleton
    2. {
    3. private static LazySingleton instance = null;
    4. //程序运行时创建一个静态只读的辅助对象
    5. private static readonly object syncRoot = new object();
    6. private LazySingleton() { }
    7. public static LazySingleton GetInstance()
    8. {
    9. //第一重判断,先判断实例是否存在,不存在再加锁处理
    10. if (instance == null)
    11. {
    12. //加锁的程序在某一时刻只允许一个线程访问
    13. lock(syncRoot)
    14. {
    15. //第二重判断
    16. if(instance==null)
    17. {
    18. instance = new LazySingleton(); //创建单例实例
    19. }
    20. }
    21. }
    22. return instance;
    23. }
    24. }

    类图:

    适用性:

    系统 只需要一个实例对象 ,或者因为资源消耗太大而 只允许创建一个对象
    客户调用类的单个实例 只允许使用一个公共访问点 ,除了该公共访问点,不能通过其他途径访问该实例

    优点:

    提供了 对唯一实例的受控访问
    可以 节约系统资源 提高系统的性能
    允许可变数目的实例( 多例类

    缺点:

    扩展困难 (缺少抽象层)
    单例类的 职责过重
    由于自动垃圾回收机制,可能会导致共享的单例对象的 状态丢失


    案例1:(.NET代码)

    1. using System;
    2. namespace SingletonSample
    3. {
    4. class Program
    5. {
    6. static void Main(string[] args)
    7. {
    8. //创建四个LoadBalancer对象
    9. LoadBalancer balancer1,balancer2,balancer3,balancer4;
    10. balancer1 = LoadBalancer.GetLoadBalancer();
    11. balancer2 = LoadBalancer.GetLoadBalancer();
    12. balancer3 = LoadBalancer.GetLoadBalancer();
    13. balancer4 = LoadBalancer.GetLoadBalancer();
    14. //判断服务器负载均衡器是否相同
    15. if (balancer1 == balancer2 && balancer2 == balancer3 && balancer3 == balancer4)
    16. {
    17. Console.WriteLine("服务器负载均衡器具有唯一性!");
    18. }
    19. //增加服务器
    20. balancer1.AddServer("Server 1");
    21. balancer1.AddServer("Server 2");
    22. balancer1.AddServer("Server 3");
    23. balancer1.AddServer("Server 4");
    24. //模拟客户端请求的分发,如果输出结果全为同一个server,可以将i适当放大,例如改为"i < 100"
    25. for (int i = 0; i < 10; i++)
    26. {
    27. string server = balancer1.GetServer();
    28. Console.WriteLine("分发请求至服务器: " + server);
    29. }
    30. Console.Read();
    31. }
    32. }
    33. }
    1. using System;
    2. using System.Collections;
    3. namespace SingletonSample
    4. {
    5. class LoadBalancer
    6. {
    7. //私有静态成员变量,存储唯一实例
    8. private static LoadBalancer instance = null;
    9. //服务器集合
    10. private ArrayList serverList = null;
    11. //私有构造函数
    12. private LoadBalancer()
    13. {
    14. serverList = new ArrayList();
    15. }
    16. //公有静态成员方法,返回唯一实例
    17. public static LoadBalancer GetLoadBalancer()
    18. {
    19. if (instance == null)
    20. {
    21. instance = new LoadBalancer();
    22. }
    23. return instance;
    24. }
    25. //增加服务器
    26. public void AddServer(string server)
    27. {
    28. serverList.Add(server);
    29. }
    30. //删除服务器
    31. public void RemoveServer(string server)
    32. {
    33. serverList.Remove(server);
    34. }
    35. //使用Random类随机获取服务器
    36. public string GetServer()
    37. {
    38. Random random = new Random();
    39. int i = random.Next(serverList.Count);
    40. return serverList[i].ToString();
    41. }
    42. }
    43. }

    案例2:(JAVA代码)

    1. public class Singleton {
    2. private static Singleton sing;
    3. private Singleton() {
    4. }
    5. public static Singleton getInstance() {
    6. if (sing == null) {
    7. sing = new Singleton();
    8. }
    9. return sing;
    10. }
    11. }
    1. public class Test {
    2. public static void main(string[] args) {
    3. Singleton sing = Singleton.getInstance();
    4. Singleton sing2 = Singleton.getInstance();
    5. System.out.println(sing);
    6. System.out.println(sing2);
    7. }
    8. }

  • 相关阅读:
    Springboot整合Prometheus-自定义指标
    嵌入式--->怎样选择编译语言,C C++或是Rust?
    计算机组成原理期中考试
    解决报错:Module Not Found Error: No module named ‘allennlp.commands.elmo‘
    Google单元测试sample分析(一)
    腾讯音乐评论审核、分类与排序算法技术
    金仓数据库KingbaseES物理备份恢复命令选项(expire命令)
    初接触:从创建工程到导出gerber(学习Altium Designer)
    HTML5 Canvas 数据持久化存储之属性列表
    C#学生信息管理系统,数据库sqlserver
  • 原文地址:https://blog.csdn.net/daobaqin/article/details/127712899