前言
单例模式 (Singleton) 是一种创建型模式,指某个类采用Singleton单例模式后,则在这个类在同一个JVM上,只可能产生一个实例供外部访问,并且仅提供一个全局的访问方式。
一、饿汉式-线程安全
线程安全,但无法实现实例懒加载策略,因为是通过静态常量定义的instance对象,所以在类加载的过程就会创建对象实例,在后续的使用中直接获取对象实例。
public class Singleton{
private static final Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
retrun instance;
}
}
二、懒汉式-线程不安全
线程不安全,但实现了懒加载机制,即使用的时候才会进行加载,不使用不会进行初始化。
private static Singleton instance= null;
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
三、全局锁式-线程安全
线程安全,使用Synchronized保证线程安全,也实现了懒加载,但是线程同步效率不高。
private static Singleton instance;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
四、静态代码块-线程安全
线程安全,在类加载的初始化阶段初始化对象实例,线程安全。
private static Singleton instance=null;
private Singleton(){
}
static{
instance = new Singleton();
}
public static Singleton getInstance(){
return instance;
}
五、双重校验锁-线程安全
线程安全,同时保证了懒加载和线程同步时的效率问题。
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance ==null){
instance = new Singleton();
}
}
}
return instance;
}
六、内部类-线程安全
线程安全,静态内部类在第一次调用时加载,且只加载一次,也实现了懒加载。
private Singleton(){
}
public static class SingletonHolder{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
七、内部枚举类-线程安全
线程安全,不存在线程同步问题,且单例对象在枚举类型 INSTANCE第一次引用时通过枚举的 构造函数初始化,从而实现了懒加载策略。
private Singleton(){
}
public enum SingletonEnum{
INSTANCE;
private final Singleton instance;
private SingletonEnum() {
instance = new Singleton();
}
}
public static Singleton getInstance(){
return SingletonEnum.INSTANCE.instance;
}
总结
单例模式的思想体现:
- 构造函数私有化;
- 对外访问的方法,返回一个该类的唯一实例对象;
- 利用静态变量、静态代码块、静态代码块和类加载机制实现单例模式以及对应的线程安全问题;
- 类加载的过程是一个线程安全的过程。