美文网首页
单例设计模式

单例设计模式

作者: X1a0Yu_ | 来源:发表于2020-02-04 16:42 被阅读0次

    既然来了简书,总要留下点什么.......

    读书养才气,勤奋养运气,宽厚养大气,淡泊养志气

    倚天屠龙记.jpg

    1-What

    保证一个类在任何情况下在程序中都绝对只有一个实例,并且提供一个全局访问点。

    2-Premise

    1.构造函数私有,防止被外部new对象;
    2.内部必须提供一个静态的方法,让外部调用。

    3-Advantage

    减少内存开销;
    避免资源多重占用。

    4-Disadvantage

    不易扩展。

    5-Classify

    5-1-饿汉式

    类加载过程中,就已经创建了实例。

    public class SingletonE {
        //静态修饰的实例,类在加载时就是执行实例化操作
        private static SingletonE mInstance = new SingletonE();
        //构造函数私有化,使外界无法创建实例
        private SingletonE(){
        }
        //为外界提供获取实例的方法
        public static SingletonE getInstance(){
            return mInstance;
        }
    }
    

    也可以通过静态代码块方法初始化。

    不足:浪费内存空间;代码不灵活。

    5-2-懒汉式

    当需要使用类的时候,才去实例化。

    public class SingletonL {
    
        private static SingletonL mInstance;
    
        private SingletonL(){}
    
        public static SingletonL getInstance(){
            if (mInstance == null){ //null判断
                mInstance = new SingletonL();
            }
            return mInstance;
        }
        
    }
    

    不足:多线程中不能保证只创建一次实例。(多线程并发)
    解决方法:加锁——synchronized

    public synchronized static SingletonL getInstance(){
            if (mInstance == null){ //null判断
                mInstance = new SingletonL();
            }
            return mInstance;
    }
    

    不足:虽然解决了线程安全的问题,但是方法每次调用的时候,都会进行同步检查,造成效率低。
    解决方法:双重检查锁——减少同步检查范围

    public static SingletonL getInstance(){
            if (mInstance == null){
                synchronized (SingletonL.class){ //同步检查
                    if (mInstance == null){
                        mInstance = new SingletonL();
                    }
                }
            }
            return mInstance;
        }
    

    不足:mInstance可能未初始化,用户获取的对象是空的
    原因:Java虚拟机的指令:
    1.给对象分配内存;
    2.调用方法初始化对象;
    3.将对象与内存关联,赋值。
    但是Java多线程中,步骤2和3的执行顺序不是固定的。

    解决方法volatile的使用 1.防止重排序;2.保证对象可见性。某一线程改了变量,短时间内该变量在另一个线程可能是不可见的,因为每一个线程都有自己的缓存区。

    private static volatile SingletonL mInstance;
    
    5-3-静态内部类
    public class SingletonS {
        private SingletonS(){
    
        }
    
        public static SingletonS getInstance(){
            return SingletonHolder.mInstance;
        }
    
        public static class SingletonHolder{
            private static SingletonS mInstance = new SingletonS();
        }
    }
    

    好处:既保证线程安全,又实现了懒加载。

    5-4-静态代码块结合容器(HashMap)
     private static Map<String,Object> map = new HashMap<>();
     static {
         map.put("single",new SingletonS());
     }
    

    除了上述的几种方式外,枚举也能实现单例,而且是最简单的,但是也存在一种问题——代码不灵活。所以,究竟选择哪一种方式实现单例,还是根据开发者自己以及项目需求。

    6-Where

    Activity管理

    参考文章:

    https://segmentfault.com/a/1190000018494382
    https://blog.csdn.net/qq_25333681/article/details/93662660

    相关文章

      网友评论

          本文标题:单例设计模式

          本文链接:https://www.haomeiwen.com/subject/qewhxhtx.html