单例模式的多种写法

Posted on 2017-12-13 19:39  冠军33  阅读(211)  评论(0编辑  收藏  举报
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;   //返回临时变量
    }
}

 

Copyright © 2024 冠军33
Powered by .NET 9.0 on Kubernetes