美文网首页程序员设计模式
单例设计模式——我是一条美丽的单身狗

单例设计模式——我是一条美丽的单身狗

作者: 0ur | 来源:发表于2018-11-26 22:53 被阅读52次

    一只100KG的大菜鸟,正在努力学习中,如有出入,往大佬扶正,谢谢!!!

    饿汉式 :

    线程安全 ,如果单例用不到 ,造成了内存的开销 .

     public  class HungrySingle {
            private static HungrySingle mHungrySingle = new HungrySingle();
    
            private HungrySingle() {
    
            }
    
            public static HungrySingle getInstance() {
                return mHungrySingle;
            }
        }
    

    懒汉式:

    线程不安全的, 在多线程环境下, 并不能做到单例.

        public  class LazybonesSingle {
    
            private static LazybonesSingle mLazybonesSingle;
    
            //私有构造
            private LazybonesSingle() {
    
            }
    
            //对外提供访问方法
            public  LazybonesSingle getInstance() {
                //如果两个线程同时调永走到 ==null的时候  可能会创建两个对象
                if (mLazybonesSingle == null) {
                    mLazybonesSingle = new LazybonesSingle();
                }
                return mLazybonesSingle;
            }
    
        }
    

    懒汉式:

    线程安全 ,获取实例的时候,每次都走同步,造成了不必要的开销.

     public class LazybonesSingleSafe {
    
            private static LazybonesSingle mLazybonesSingle;
    
            private LazybonesSingleSafe() {
    
            }
     
            public synchronized static LazybonesSingle getInstance() {
                if (mLazybonesSingle == null) {
                    mLazybonesSingle = new LazybonesSingle();
                }
                return mLazybonesSingle;
            }
    
        }
    

    DCL(双重锁验证)式:

    减少了每次同步的开销 ,还保证了懒加载 ,但是在高并发的情况下,还有可能造成多实例的存在.

    public class LazyboneSingleDCL {
            private static volatile LazyboneSingleDCL mLazyboneSingleDCL;
    
            private LazyboneSingleDCL() {
    
            }
    
            public static LazyboneSingleDCL getInstance() {
                //如果为空 进入同步   不等空 直接取走对象  减少了同步的开支
                if (mLazyboneSingleDCL == null) {
                    //如果为空 确保只有一个线程进入
                    synchronized (LazyboneSingleDCL.class) {
                        //防止多线程 进入 再次判断如果对象不为空 直接取值
                        if (mLazyboneSingleDCL == null) {
                            mLazyboneSingleDCL = new LazyboneSingleDCL();
                        }
                    }
                }
                return mLazyboneSingleDCL;
            }
        }
    

    静态内部类式:

    java高并发,描述DCL是丑陋的,解决方案是用 静态内部类来解决.
    JVM的类加载方式(虚拟机会保证一个类的初始化在多线程环境中被正确的加锁、同步), 来保证了多线程并发访问的正确性.
    这种方式是一种比较完美的单例模式. 当然, 它也有其弊端, 依赖特定编程语言, 适用于JAVA平台.

        public class StaticInnerClassForm {
            private StaticInnerClassForm() {
    
            }
    
            public static StaticInnerClassForm getInstance() {
                return FormHolder.INSTANCE;
            }
    
            private static class FormHolder {
                private static StaticInnerClassForm INSTANCE = new StaticInnerClassForm();
            }
    
        }
    

    以上单例,存在一种情况可以再次创建对象 反序列化 以上方法为了不让序列化创建对象 加入readResolve()方法 可以保证

    枚举式:

    单例,默认线程安全,任何情况下都保证对象唯一.

     public enum SingletonEnum {
    
            INSTANCE;
    
            public void doSomething() {
    
            }
    
        }
    

    容器单例式:

    android的各种服务的单例使用Map来储存的.

       public class SingleMap {
    
           private static Map<String, Object> mSingMap = new HashMap<>();
    
           private SingleMap() {
    
           }
    
           public void registerSingleService(String key, Object value) {
               if (!mSingMap.containsKey(key)) {
                   mSingMap.put(key, value);
               }
           }
    
           public Object getService(String key) {
               //如果没有这个值的要抛出异常
               return mSingMap.get(key);
    
           }
       }
    

    大佬,点个赞再走也不迟,小姐姐正在洗澡~~~

    相关文章

      网友评论

        本文标题:单例设计模式——我是一条美丽的单身狗

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