• 深入浅出单例模式


    一、单例模式的优点:

    - 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决

    - 单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理

    二、常见的五种单例模式实现方式:

    - 主要

    • 饿汉式(线程安全,调用效率高。但是,不能延时加载。)
    • 懒汉式(线程安全,调用效率不高。但是,可以延时加载。)

    - 其他:

    • 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)
    • 静态内部类式(线程安全,调用效率高。可以延时加载)
    • 枚举单例(线程安全,调用效率高,不能延时加载)

      ①饿汉式实现(单例对象立即加载)

    饿汉式单例模式代码中,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题。因此,可以省略synchronized关键字。

    问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费!

    /**
     * 饿汉式单例模式
     * @author t
     */
    public class SingletonDemo01 {
    
        private static SingletonDemo01 singletonDemo01 = new SingletonDemo01();
    
        private SingletonDemo01(){
    
        }
    
        public static SingletonDemo01 getInstance(){
            return singletonDemo01;
        }
    } 

     ②懒汉式实现(单例对象延迟加载)

    /**
     * 懒汉式单例模式
     * @author t
     */
    public class SingletonDemo02 {
    
        private static SingletonDemo02 singletonDemo02 = null;
        private SingletonDemo02(){
    
        }
    
        public static synchronized SingletonDemo02 getInstance(){
            if (singletonDemo02==null){
                singletonDemo02 = new SingletonDemo02();
            }
            return singletonDemo02;
        }
    }

      ③双重检测锁实现

      这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步创建了以后就没必要了

      问题:由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用。

    /**
     * 双重检测锁实现单例模式
     * @author t
     */
    public class SingletonDemo03 {
    
        private static SingletonDemo03 singletonDemo03 = null;
        private SingletonDemo03(){
    
        }
    
        public static SingletonDemo03 getInstance(){
            if (singletonDemo03 == null){
                SingletonDemo03 sc;
                synchronized (SingletonDemo03.class){
                    sc = singletonDemo03;
                    if (sc == null){
                        synchronized (SingletonDemo03.class){
                            if (sc == null){
                                sc = new SingletonDemo03();
                            }
                        }
                        singletonDemo03 = sc;
                    }
                }
    
            }
            return singletonDemo03;
        }
    }

     ④内部类实现(懒加载)

    /**
     * 静态内部类实现单例模式(懒加载)
     * @author t
     */
    public class SingletonDemo04 {
    
        private static class SingletonClassInstance{
            private static SingletonDemo04 singletonDemo04 = new SingletonDemo04();
        }
        
        private SingletonDemo04(){
            
        }
        
        public static SingletonDemo04 getInstance(){
            return SingletonClassInstance.singletonDemo04;
        }
    }

    要点:

    外部类没有static属性,则不会像饿汉式那样立即加载对象。

    只有真正调用getInstance(),才会加载静态内部类。加载类时线程时安全的。instance时static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性。

    兼备了并发高效调用和延迟加载的优势

     ⑤枚举式实现

    /**
     * 枚举式实现单例模式
     * @author t
     */
    public enum SingletonDemo05 {
    
        //这个枚举元素,本身就是单例对象
        INSTANCE;
    
        public void hello(){
            System.out.println("hello");
        }
    }
  • 相关阅读:
    CCS3.3安装常见问题(以合众达的为例)
    typedef unsigned long (__stdcall *THREADFUNC)(void *)
    Prism学习(8)模块间通讯
    Prism学习(6)Shell Region View
    Prism学习(4)弃远就近UnityBootstrapper
    Prism学习(2)初识Unity
    Prism学习(5)Hello Silverlight
    Prism学习(1)前期准备
    Prism学习(7)Commands
    Prism学习(9)阶段性总结
  • 原文地址:https://www.cnblogs.com/ushowtime/p/12284352.html
Copyright © 2020-2023  润新知