欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

双重检查单例学习

程序员文章站 2022-07-10 20:58:35
单例模式是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

相关标签: JAVA