• 单例模式的多种写法


    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;   //返回临时变量
        }
    }
  • 相关阅读:
    使用dataInput:DescriptionViewer对输入的数据进行校验
    Nunit2.6.2调试.net4类库
    使用WCF RIA服务支持ASP.NET验证
    偶遇 Lc.exe已退出代码为1
    android程序连接后端web service时,提示:Permission denied
    设置XP系统的自动登录
    DomainDataSource的自动刷新
    安装CentOS时,显示 NET:Registered protocol family 2
    清除SqlServer2008的日志
    http://www.cnblogs.com/KnightsWarrior/archive/2010/08/27/1809739.html(博客主)
  • 原文地址:https://www.cnblogs.com/caoyajun33-blog/p/8034567.html
Copyright © 2020-2023  润新知