单例模式的几种写法

一、懒汉式(线程不安全)


public class Singleton {

private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (null == instance) {
instance = new Singleton();
}
return instance;
}

}

二、懒汉式(线程安全使用synchnorized关键字)

public class Singleton {

    private static Singleton instance;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if (null == instance) {
            instance = new Singleton();
        }
        return instance;
    }

}

三、饿汉式

public class Singleton {

    private static Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}

四、双重检验锁(线程安全)

public class Singleton {

    private volatile static Singleton instance;
    private Singleton(){}
    public static Singleton getInstance(){
        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

QA:

Q:为什么使用volatile关键字?

A:jvm虚拟机在执行时有可能做优化(指令重排序优化),synchronized只可能保证同步代码块内原子性(注:synchronized代码块内的代码仍可能发生有序性问题,即指令重排序),但是无法保证外面if判断。啥意思呢?

当T1线程执行到同步代码块内,发生了指令重排序,先将对象的引用赋值给了static Instance,那么此时T2执行到同步代码块外面的if判断,就会发现Instance不为Null,就继续执行返回,可返回的时候,T1还未将构造方法初始完毕,对Instance使用volatile修饰即可,可以禁止指令重排序。

 

posted @ 2021-03-26 08:49  _小郑  阅读(50)  评论(0)    收藏  举报