单例模式
单例模式:顾名思义,单例模式的意思就是只有一个实例,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类被称为单例类
接下来,就是单例模式的所有用法
饿汉式
public class Singleton {
private static final Singleton instance1 = new Singleton();
//构造方法设置成私有
private Singleton() {}
//暴露一个公共方法,来把SingLine对象传递出去 饿汉式
public static Singleton getSingLine() {
return instance1;
}
优点:线程安全,在类加载的同时就已经创建好对象,加载速度块
缺点:资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化
懒汉式
public class Singleton2 {
private static Singleton2 instance2;
//构造方法设置成私有
private Singleton2() {}
public static synchronized Singleton2 getInstance() {
if (instance2 == null)
instance2 = new Singleton2();
return instance2;
}
}
优点:只在第一次使用的时候调用,一定程度上节省了资源
缺点:第一次加载需要进行及时实例化,反应稍慢,最大的问题是每次调用getInstance 都进行同步,造成不必要的同步开销,这种模式一般不推荐使用
Double Check Lool (DCL)实现单例
JDK 为15 以后的版本,需要将定义加上一个关键字volatile 就能保证对象每次都是从主内存中取出
DCL 模式是使用最多的单例实现方式,它能够在需要时才实例化对象,并且能够在大多数情况下保证单例对象的唯一性。
public class Singleton3 {
private volatile static Singleton3 instance3 = null;
//构造方法私有
private Singleton3() {
}
public static Singleton3 getInstance() {
//进行两次非空判断 ,第一层是为了避免不必要的同步
if (instance3 == null) {
//获取Singleton3.class的锁,避免实例化多次
synchronized (Singleton3.class) {
if (instance3 == null) {
instance3 = new Singleton3();
}
}
}
return instance3;
}
}
优点:
1. 既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance不进行同步锁。
2. 资源利用率高,第一次执行geinstance的时候才被实例化,效率高
缺点:第一次加载反应稍慢,也由于Java内存模型的原因偶尔会失败,在高并发环境下也有一定的缺陷。
静态内部类实现单例
public class Singleton4 {
private Singleton4() {
}
public static Singleton4 getInstance() {
return SingLineHolder.instance4;
}
private static class SingLineHolder {
private static final Singleton4 instance4 = new Singleton4();
}
}
}
优点:确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化,所以这是推荐使用的单例模式实现方式
以上就是单例模式的几种实现方式啦,蟹蟹大家,喜欢就点个赞吧!