单例模式优秀写法

public class demo02 {
    private static volatile demo02 INSTANCE;

    private demo02(){}

    public static demo02 getINSTANCE(){
        if (INSTANCE == null){
            synchronized (demo02.class){
                if (INSTANCE == null){
                    try {
                        Thread.sleep(1);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
                INSTANCE = new demo02();
            }
        }
        return INSTANCE;
    }

    public void d(){
        System.out.println("d");
    }

    public static void main(String[] args){
        for (int i = 0 ; i < 100; i++){
            new Thread(() ->{
                System.out.println(demo02.getINSTANCE().hashCode());
            }).start();
        }
    }
}
1、
暂不初始化对象,直到有其他对象或方法来调用时再进行初始化,避免造成不必要的初始化,减少内存空间;
2、
多线程访问时,加锁
3、
在其他对象使用该类,调用getInstance()方法的时候进行初始化,并且进行double check null ,double check null 的目的是在多线程的时候会造成多次new,而导致不是同一个对象也不是同一内存地址;
3、
volatile关键字的作用是,原子性(某些情况下不具备原子性),以及多线程之间的可见性,并且还有一点重要的是可以防止指令重排;
指令重排:
在一个class 通过class loader调用后进入内存中,到达linking阶段,linking阶段包括verification(验证) -> preparation(准备) -> resolution(解析);
preparation阶段为clss->静态变量赋默认值(类的初始化),而在这一阶段可能会发生指令重排,(在其汇编代码内指令执行的顺序会发生变化)

  

猜你喜欢

转载自www.cnblogs.com/felix-fang/p/11705046.html