单例模式
一、饿汉式
/**
* @Author 吕小白
* @ClassName Eager
* @Description:单例模式——饿汉式
* @Date 2021/6/24 9:01
* @Version 1.0
**/
public class Eager {
// 创建实例对象
private static Eager eager=new Eager();
//将构造函数私有化
private Eager(){
}
// 创建获取单例对象的方法
public static Eager getInstance(){
return eager;
};
}
二、懒汉式
1、在获取单例对象时判断是否为空,存在线程安全问题
/**
* @Author 吕小白
* @ClassName Sluggard
* @Description:单例模式——懒汉式(判断是否为空、存在线程安全问题)
* @Date 2021/6/24 9:10
* @Version 1.0
**/
public class Sluggard {
//定义懒汉式单例对象
private static Sluggard sluggard;
// 将构造器私有化
private Sluggard(){
}
/**
* 获取懒汉式单例对象的方法
*/
public static Sluggard getInstance(){
if(sluggard==null){
sluggard=new Sluggard();
return sluggard;
}
return sluggard;
}
}
2、添加同步方法,双重检验,不防止反射、序列化破环
/**
* @Author 吕小白
* @ClassName Sluggard
* @Description:单例模式——DCL懒汉式(同步方法双重检验)
* @Date 2021/6/24 9:10
* @Version 1.0
**/
public class Sluggard {
//定义懒汉式单例对象
//volatile防止指令重排,因为new Sluggard()并不是一步操作,1、分配内存空间 2、初始换对象 3、将对象指向内存空间
private volatile static Sluggard sluggard;
// 将构造器私有化
private Sluggard(){
}
/**
* 获取懒汉式单例对象的方法
*/
public static Sluggard getInstance(){
if(sluggard==null){
synchronized (Sluggard.class){
if(sluggard==null){
sluggard=new Sluggard();
return sluggard;
}
}
}
return sluggard;
}
}
3、使用静态内部类
/**
* @Author 吕小白
* @ClassName Sluggard
* @Description:单例模式——懒汉式(静态内部类)
* @Date 2021/6/24 9:10
* @Version 1.0
**/
public class Sluggard {
// 将构造器私有化
private Sluggard(){
}
// 创建静态内部类
private static class SluggardHolder{
//定义懒汉式单例对象
private static final Sluggard sluggard=new Sluggard();
}
/**
* 获取懒汉式单例对象的方法
*/
public static Sluggard getInstance(){
return SluggardHolder.sluggard;
}
}
4、使用枚举,防止反射
/**
* @Author 吕小白
* @ClassName Sluggard
* @Description:单例模式——懒汉式(枚举)
* @Date 2021/6/24 9:10
* @Version 1.0
**/
public class Sluggard {
// 将构造器私有化
private Sluggard(){
}
//创建枚举获取单例对象
private enum NewInstance{
INSTANCE;
// 定义单例对象
private Sluggard sluggard;
NewInstance(){
// 初始化单例对象
sluggard=new Sluggard();
}
//获取单例对象
private Sluggard getInstance(){
return sluggard;
}
}
/**
* 获取懒汉式单例对象的方法
*/
public static Sluggard getInstance(){
return NewInstance.INSTANCE.getInstance();
}
}