7 种单例模式设计

作者: Tim在路上 | 来源:发表于2019-11-05 17:25 被阅读0次

    饿汉式

    // final 不允许被继承 
    public final class Singleton {
        
        // 饿汉式,先new
        private static Singleton singleton = new Singleton();
        
        // 私有构造不允许外部 new
        private Singleton(){
            
        }
        
        public static Singleton getInstance(){
            return singleton;
        }
        
    }
    

    饿汉式的问题是 instance 在被 ClassLoader加载后很长时间才能在使用,如果类中的资源是重资源,那么就必须使用懒汉式

    懒汉式

    // final 不允许被继承
    public final class Singleton {
    
        // 饿汉式,先new
        private static Singleton singleton = null;
    
        // 私有构造不允许外部 new
        private Singleton(){
            
        }
    
        public static Singleton getInstance(){
            if (singleton == null){
                singleton = new Singleton();
            }
            return singleton;
        }
        
    }
    

    问题是多线程下不能保证实例的唯一性。

    懒汉式+ 同步

    // 但是 只允许一个 线程 访问这个方法 ,效率就会很低

    // final 不允许被继承
    public final class Singleton {
    
        // 饿汉式,先new
        private static Singleton singleton = null;
    
        // 私有构造不允许外部 new
        private Singleton(){
    
        }
    
        public static synchronized Singleton getInstance(){
            if (singleton == null){
                singleton = new Singleton();
            }
            return singleton;
        }
    
    }
    

    Double-check

    //

    // final 不允许被继承
    public final class Singleton {
    
        // 饿汉式,先new
        // 不加 volatile 可能出现空指针异常 ,可能JVM指令的重排序
        private volatile static Singleton singleton = null;
    
        // 私有构造不允许外部 new
        private Singleton(){
        }
        // 双重校验,可以进入方法
        public static  Singleton getInstance(){
            if (singleton == null){
                synchronized(Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    

    Holder 实现静态的私有内部类

    // final 不允许被继承
    public final class Singleton {
        
        // 私有构造不允许外部 new
        private Singleton(){
             
        }
    
        private static class Holder{
            private static Singleton instance = new Singleton();
        }
    
        public static Singleton getInstance(){
            return Holder.instance;
        }
    }
    

    Singleton 类中,初始化过程中并不会创建 Singleton 的实例 ,只有当 Holder 类被主动引用的时候则会创建

    枚举方式

    枚举的方式不允许被继承,同时是线程安全的 ,只能被实例化一次

    推荐使用枚举的方式

    饿汉式

    public enum  Singleton {
    
        INSTANCE;
        // 私有构造不允许外部 new
        private Singleton(){
            System.out.println("Instance will be init immediately");
        }
        //
        public static Singleton getInstance(){
            return INSTANCE;
        }
    }
    

    // 懒加载

    把枚举作为内部类进行懒加载

    public class Singleton {
    
        private Singleton(){
    
        }
    
        private enum EnumHolder{
            INSTANCE;
            private Singleton instance;
            
            EnumHolder(){
                this.instance = new Singleton();
            }
            
            private Singleton getInstance(){
                return instance;
            }
        }
        
        public static Singleton getInstance(){
            return EnumHolder.INSTANCE.getInstance();
        }
    }
    

    相关文章

      网友评论

        本文标题:7 种单例模式设计

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