zoukankan      html  css  js  c++  java
  • 单例模式——Singleton

    模式分类:

    从目的来看:
    1.创建型(Creational)模式:负责对象创建。
    2.结构型(Structural)模式:处理类于对象间的组合。
    3.行为型(Behavioral)模式:类与对象交互中的职责分配。
    从范围看:
    1.类模式处理类于子类的静态关系。
    2.对象模式处理对象间的动态关系。

    动机

    在软件系统中,经常有一些这样特殊的类,必须保证他们在系统中只存在一个实例,才能确保他们的逻辑正确性、以及良好的效率。
    绕过常规的构造器,提供一种机制保证一个类只有一个实例。

    意图

    保证一个类仅有一个实例,并提供一个该实例的全局访问点。

    结构

    单线程Singleton模式实现:

    public class Singleton
    {
        private static Singleton Instance;
        private Singleton() {}
        
        public static Singleton Instance
        {
            get
            {
                if(instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
    或者:
    public class Singleton
    {
        private static Singleton Instance = new Singleton();
        private Singleton() {}
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
    }

    两者有啥区别?

    第一种可以做到LazyLoad。
    判断对象的引用:
    Object.ReferenceEquals(t1,t2)

    单线程Singleton模式的几个要点

    1.单例模式可以设置为protected允许派生子类。
    2.单例模式一般不支持ICloneable接口,这可以导致多个实例,于单例模式初衷违背。
    3.单例模式不要支持序列化,序列化,反序列化形成了深拷贝,于单例模式初衷违背
    4.单例模式没有考虑对象销毁,对于存在垃圾回收的平台不需要考虑,一般不会让类很大。所以消耗很小
    5.不能应对多线程环境:在多线程环境下,使用Singleton模式仍有可能得到Singleton类的多个实例对象。

    多线程Singleton模式

    public class Singleton
    {
        private static volatile Singleton Instance = ;
        private static object lockHelper = new Object();
        private Singleton() {}
        public static Singleton Instance
        {
            get
            {
                if(instance == null)
                {
                    lock(lockHelper)
                    {
                        if(instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }
    双检查(Double Check):就是为了防止多线程的实例创建。
    编译器代码编译的时候,会进行代码顺序微调,加了volatile保证代码编译不调整指令。
    class Singleton
    {
        public static readonly Singleton Instance = new Singleton();
        private Singleton() {}
    }

    class Singleton
    {
        public static readonly Singleton Instance;
        static Singleton()
        {
            Instance = new Singleton();
        }
        private Singleton();
    }
    的效果是一样的。
    静态构造器的角色:
    1.静态构造器的执行时间:只在静态字段初始化之前初始化。(内敛初始化会把初始化放到静态构造器中初始化。)
    beforefieldinit
    2.dot net 机制保证了静态构造器确保了只有一个执行静态构造器。不会有多个静态构造器执行。
    3.不支持参数的构造器。

    使用.Net类型初始化机制实现多线程Singleton模式

    public class Singleton
    {
        private static Singleton instance;
        private Singleton(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public static Singleton GetInstance(int x, int y)
        {
            if (instance == null)
            {
                instance = new Singleton(x, y);
            }
            else
            {
                instance.x = x;
                instance.y = y;
            }
            return instance;
        }
    }

    Singleton模式扩展

    1.将一个实例扩展到n个实例,例如对象池的实现。(其实就是控制构造的过程,Singleton就是控制对象的个数)
    2.将new构造器的调用转移到其他类中,例如多个协同工作环境中,某个局部环境只需要拥有某个累的一个实例
    3.理解Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用。”
  • 相关阅读:
    Java反射机制源码分析及知识点总结
    Dubbo admin 在Windows下的安装和服务发现
    Redis知识点总结
    Error:(xx) java: -source 1.5 中不支持
    Java中的线程间通信
    linux主机名显示bogon问题
    Linux(CentOS)上安装Apache Hadoop
    Java虚拟机(JVM)及其体系结构
    在微服务领域中处理分布式事务
    Redis持久化
  • 原文地址:https://www.cnblogs.com/9527y/p/3923458.html
Copyright © 2011-2022 走看看