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 ]

  • 相关阅读:
    AutoLISP批量移动图元到指定图层
    AutoLISP实现同时绘制多条直线
    再测试下连接微博
    一个博士的论文致谢词
    AutoLISP实现橡皮筋绘图预览
    AutoLISP根据所选图元冻结图层
    AutoCAD中绘制箭头
    你是谁的流川枫
    AutoLISP反应器vlrobjectreactor函数应用
    AutoLISP实时跟踪鼠标坐标
  • 原文地址:https://www.cnblogs.com/crazytrip/p/6676838.html
Copyright © 2011-2022 走看看