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

    1、单例模式定义

    在整个应用中,同一时刻,有且只能有一种状态的类可以考虑写成单例模式;

    2、单例模式的好处

    节约内存空间,减少无谓的GC消耗;

    3、单例模式示例代码

    3.1 标准的单例模式- 这种是在不考虑并发的情况下的代码,所以不是很严谨;

    public class Singleton {
    
        //一个静态的实例
        private static Singleton singleton;
        //私有化构造函数
        private Singleton(){}
        //给出一个公共的静态方法返回一个单一实例
        public static Singleton getInstance(){
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }

    3.2 为防止并发的情况实例化多个破坏单例模式,以下代码加了同步锁来避免这种情况;

    public class SynchronizedSingleton {
    
        //一个静态的实例
        private static SynchronizedSingleton synchronizedSingleton;
        //私有化构造函数
        private SynchronizedSingleton(){}
        //给出一个公共的静态方法返回一个单一实例
        public synchronized static SynchronizedSingleton getInstance(){
            if (synchronizedSingleton == null) {
                synchronizedSingleton = new SynchronizedSingleton();
            }
            return synchronizedSingleton;
        }
        
    }

    3.3 上面3.2的这种在方法上加同步锁的做法可以避免产生多个实例的问题,在一个线程访问这个方法时,其它所有的线程都要处于挂起等待状态,但是在实例创建以后,获取实例的方法就没必要再进行同步控制了;所以,可以考虑把同步锁往下放,放到产生实例的语句块上,来形成一个同步语句块锁;

    public class SynchronizedSingleton {
    
        //一个静态的实例
        private static SynchronizedSingleton synchronizedSingleton;
        //私有化构造函数
        private SynchronizedSingleton(){}
        //给出一个公共的静态方法返回一个单一实例
        public static SynchronizedSingleton getInstance(){
            if (synchronizedSingleton == null) { //(1)
                synchronized (SynchronizedSingleton.class) { //同步语句块  
                    if (synchronizedSingleton == null) { //这里进行了又一次判断,是为了防止线程A创建完实例释放同步锁,线程B已经过了语句“(1)”的判断进入同步块继续创建实例;
                        synchronizedSingleton = new SynchronizedSingleton();
                    }
                }
            }
            return synchronizedSingleton;
        }
    }

    假设我们去掉同步块中的是否为null的判断,有这样一种情况,假设A线程和B线程都在同步块外面判断了synchronizedSingleton为null,结果A线程首先获得了线程锁,进入了同步块,然后A线程会创造一个实例,此时synchronizedSingleton已经被赋予了实例,A线程退出同步块,直接返回了第一个创造的实例,此时B线程获得线程锁,也进入同步块,此时A线程其实已经创造好了实例,B线程正常情况应该直接返回的,但是因为同步块里没有判断是否为null,直接就是一条创建实例的语句,所以B线程也会创造一个实例返回,此时就造成创造了多个实例的情况。

    [以上内容摘自博客园:http://www.cnblogs.com/zuoxiaolong/p/pattern2.html ]

  • 相关阅读:
    借助浏览器流特性设置宽度
    元素类型的转换
    浮动
    【华为云技术分享】【DevCloud · 敏捷智库】软件开发团队如何管理琐碎、突发性任务(内附下载材料)
    【华为云技术分享】从项目实际问题引发的思考
    【华为云技术分享】文言文也能编程?此诚年度最骚语言也
    【华为云技术分享】这种反爬虫手段有点意思,看我破了它!
    【华为云技术分享】华为云获CCF BDCI 2019金融实体级情感分析大赛冠军
    【华为云技术分享】【鲲鹏来了】鲲鹏迁移过程案例分享
    【华为云技术分享】非编程人学Python,要注意哪些隐秘的错误认知?
  • 原文地址:https://www.cnblogs.com/crazytrip/p/6676838.html
Copyright © 2011-2022 走看看