携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
单例模式
单例模式设计到一个单一的类,该类负责创建自己的对象,并且有且只有一个对象能够被创建。并且该类提供了访问其唯一对象的方法,不需要客户端实例该对象
单例模式的结构
- 单例类:只能创建一个实例的类
- 访问类:使用实例的类
单例模式的实现方式
- 饿汉式:类加载时,就会创建该对象
- 懒汉式:类加载时不会创建该对象,首次使用该对象时才会创建
饿汉式实现方式
静态变量方式
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static final Singleton instance = new Singleton();
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
缺点:会造成内存浪费
静态代码块方式
public class Singleton{
private Singleton(){}
private static Singleton instance;
static{
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
缺点:同上,会造成内存浪费
枚举
public enum Singleton {
INSTANCE;
}
说明:极力推荐,因为枚举类型是线程安全的,并且只会装载一次唯一一种不会被破坏的单例实现模式
懒汉式实现方式
方式1--线程不安全
public class Singleton{
private Singleton(){}
private static Singletion instance;
public static Singletion getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
问题: 会造成线程安全问题,可能会创建出多个对象
方式2--线程安全
public class Singleton{
private Singleton(){}
priavte static Singleton instance;
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
问题:线程安全,但是执行效率低
方式3--双检查模式--线程安全
public class Singleton{
private Singleton(){}
//violatile是解决JVM在实例化对象的时候会进行优化和指令重排序操作
priavte static volatile Singleton instance;
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
方式4--静态内部类
/**
* 静态内部类方式
*/
public class Singleton {
//私有构造方法
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
说明:静态内部类在外类加载时不会进行初始化,在调用才会初始化,而且类加载是线程安全的