单例模式的几种写法
一、懒汉式(线程不安全)
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修饰即可,可以禁止指令重排序。

浙公网安备 33010602011771号