当前位置: 移动技术网 > IT编程>开发语言>Java > 双重检查单例学习

双重检查单例学习

2020年07月22日  | 移动技术网IT编程  | 我要评论
单例模式是java开发模式最常用的一种。 今天深入学习双重检查单例。先看几种典型单例代码: private Sington(){ } // 方案1 // 最简单单例,final 保证只能new一下 // 不能接受启动就创建对象。万一不用不就浪费了? private static final Sington instans0=new Sington(); public static Sington instance0(){ retu

单例模式是java开发模式最常用的一种。 今天深入学习双重检查单例。

先看几种典型单例代码:

 private Sington(){

    }
    //  方案1
    // 最简单单例,final 保证只能new一下
    // 不能接受启动就创建对象。万一不用不就浪费了?
    private static final Sington instans0=new Sington();
    public static Sington instance0(){
        return instans0;
    }
    //  方案2
    // 方法加锁,进阶懒加载
    // 锁住了整个方法, 每次调用都lock一下也不能接受
    private static Sington instans1=null;
    public synchronized static Sington instance(){
        if(instans1==null){ 
            instans1=new Sington();
        }
        return instans1;
    }
    //  方案2 类似
    private static Sington instans2=null;
    public  static Sington instance2(){
        synchronized(Sington.class){
            if(instans2==null){
                instans2=new Sington();
            }
        }
        return instans2;
    }
    // 方案3:双重检查单例
    // 懒加载
    // 上来无脑加锁不能接受,增加null判断。 
    // 问题又来了:为啥要用volatile???
    private static volatile Sington instans3=null;
    public  static Sington instance3(){
        if(instans3==null){ 
            synchronized(Sington.class){
                if(instans3==null){
                    instans3=new Sington();
                }
            }
        }
        return instans3;
    }

重点来了:volatile 存在的意义是什么?

这里涉及了好几个知识点 ,指令重排,内存屏障,类实例化过程。

volatile 有什么特性?

  1. 线程可见
  2. 禁止指令重排序

什么是指令重排?

这里不深入解释,简单来说,在多线程环境下,cpu指令为了提升性能,对于没有绝对先后顺序的指令存在乱序执行的可能性。 

了解类的实例化

类实例化主要3个步骤实例化->初始化->返回。  在实例化过程中存在初始化还没执行,已经返回了。 

线程2拿到未初始化的实例对象, 后续时候就会报错。 

 

本文地址:https://blog.csdn.net/tkascor/article/details/107489655

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网