zoukankan      html  css  js  c++  java
  • 单例模式的多种写法

    public class Singleton {
        private Singleton(){}//私有化构造器
        
        private static Singleton instance = null;  //类的内部创建对象
        
        public static Singleton getInstance(){  //暴露公共的get方法
            if(instance == null){
                instance = new Singleton();
            }
            return instance;
        }
    }
    //饿汉
    class Singleton2{
        private Singleton2(){}
        //只实例化一次,线程安全。     但是有些浪费空间
        private static Singleton2 instance = new Singleton2();
        
        public static Singleton2 getInstance(){
            return instance;
        }
    }
    //双重检测锁 懒汉模式
    /*
     * 可能存在的问题:线程a进行第一次访问,①处为null拿到锁②也为null 执行③
     *     instance = new Singleton3() 会被编译器编译成JVM指令
     * 
     *      memory = allocate();  //1.分配内存空间
     *      ctorInstance(memory);   //2.初始化对象
     *      instance = memory;   //3.将instance指向刚分配的地址
     * 
     *      可能JVM将指令优化重排为  1 3 2 
     * 
     *  当a线程执行到3时CPU被b线程拿到,此时b线程①出不为null  直接返回instance
     *        而此时的instance只有内存地址,并没有初始化完成
     * 
     * 
     */
    class Singleton3{
        
        private Singleton3(){}
        
        private static Singleton3 instance = null;
        
        public static Singleton3 getInstance(){
            
            if(instance == null){   //
                synchronized (Singleton3.class) {
                    if(instance == null){//
                        instance = new Singleton3();  //
                    }
                }
            }
            return instance;
        }
    }
    
    //双重检测锁 懒汉模式   volatile
    class Singleton4{
        
        private Singleton4(){}
        
        //volatile  阻止指令重排、禁用线程内存      保证每次都读写主内存的值
        private volatile static Singleton4 instance = null;
        
        public static Singleton4 getInstance(){
            
            if(instance == null){
                synchronized (Singleton4.class) {
                    if(instance == null){
                        instance = new Singleton4();     //volatile修饰的变量不会指令重排   
                    }
                }
            }
            return instance;
        }
    }
    
    //双重检测锁 懒汉模式   volatile +优化
    /*
     * volatile 阻止指令重排,读取volatile修饰的变量消耗的性能会比较大
     * 
     * 所以创建临时变量,在instance不为null时,直接返回临时变量,不再去访问volatile的变量    提高25%的性能
     * 
     */
    class Singleton5{
        
        private Singleton5(){}
        
        private volatile static Singleton5 instance = null;
        
        public static Singleton5 getInstance(){
            Singleton5 inst = instance;   //创建临时变量
            
            if(instance == null){
                synchronized (Singleton5.class) {
                    if(instance == null){
                        inst = new Singleton5();
                        instance = inst;      
                    }
                }
            }
            return inst;   //返回临时变量
        }
    }
  • 相关阅读:
    JVM问题定位分析(一)
    性能分析--上下文切换(context switch)
    JVM--如何通过软引用和弱引用提JVM内存使用效率
    docker挂载文件宿主机与容器内部数据不同步问题
    使iptables规则在CentOS 7中持久化
    dstat
    curl
    Django REST framework 之JWT认证
    【区别】摘要、数字签名、数字证书
    使用django.core.mail的EmailMultiAlternatives发送邮件a标签链接不生效问题
  • 原文地址:https://www.cnblogs.com/caoyajun33-blog/p/8034567.html
Copyright © 2011-2022 走看看