单例模式是在开发中经常使用的设计模式,饿汉式自然是不存在线程安全问题的,但是为了节约系统开销,经常会 用到懒汉式。
public class Singleton {
//单例模式
//懒汉式
private static Singleton singleton=null;
private Singleton(){
}
public static Singleton getSingle(){
if (singleton==null)
return new Singleton();
return singleton;
}
}
这是最基本的懒汉式写法
懒汉式在单线程情况下不会存在问题,但是在多线程的情况下,线程安全问题不可忽略。
通过双重检测机制加锁是否能实现线程安全??
public class Singleton {
//单例模式
//懒汉式双重检测机制加锁
private static Singleton singleton=null;
private Singleton(){
}
public synchronized static Singleton getSingle(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null)
return singleton;
}
}
return singleton;
}
}
这就要从JVM和CPU优化着手进行分析了
java在创建对象的过程中主要有三个步骤
1、分配对象的内存空间
2、设置instance指向刚分配的内存
3、初始化对象
但是在创建的过程中,由于JVM和CPU优化,2和3这两个步骤是可以发生指令重排的,这就导致了多线程情况下,会返回没经过初始化的对象
如何解决?
通过volatile关键字实现多线程的可见性,标记对象创建的状态
public class Singleton {
//单例模式
private static volatile Singleton singleton=null;
private Singleton(){
}
public static Singleton getSingle(){
//双重检测机制加锁,实现线程安全
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null)
return singleton;
}
}
return singleton;
}
}