单例模式(Singleton Pattern)是一种创建型设计模式,它保证一个类只有一个实例,并提供了全局访问点。
该模式通常在需要控制某个资源的共享访问或者创建开销比较大的对象时使用。
单例模式的实现方式通常包括以下三个必要元素:
-
一个私有构造方法
-
一个静态私有实例
-
一个公开的静态访问方法。
在基本形式的单例模式中,某个类的构造方法被限定为私有,因此无法从外部直接创建该类的实例;而通过内部所持有的静态实例对象,可以提供一个全局唯一的访问点,使得外部环境可以方便地访问该实例。
需要注意的是,在多线程环境下需要考虑单例模式的线程安全性,以避免出现重复实例化的情况。对于高并发场景下的单例模式实现,通常采用双重检查锁定等机制来进行线程同步和控制。
单例模式的实现:
单例模式的常见方式有饿汉式和懒汉式两种:
-
饿汉式:在类加载完成以后就创建出单实例。后面需要用时可以直接调用。
/**
* 饿汉式
*
* @author zjj_admin
*/
public final class Singleton1 implements Serializable {
private Singleton1() {
}
private static final Singleton1 INSTANCE = new Singleton1();
public static Singleton1 getInstance() {
return INSTANCE;
}
public Object readResolve() {
return INSTANCE;
}
}
-
懒汉式:在类加载阶段不会创建单实例,只有在第一次调用时才会创建。在后续调用时就可以直接使用了。
/**
* 懒汉式
*
* @author zjj_admin
*/
public final class Singleton2 {
private Singleton2() {
}
private static volatile Singleton2 INSTANCE = null;
public static Singleton2 getInstance() {
if (INSTANCE != null) {
return INSTANCE;
}
synchronized (Singleton2.class) {
if (INSTANCE != null) {
return INSTANCE;
}
INSTANCE = new Singleton2();
return INSTANCE;
}
}
}
测试:从结果可以看出,创建多个实例实际用的都是同一个。
public static void main(String[] args) {
Singleton1 instance1 = Singleton1.getInstance();
Singleton1 instance2 = Singleton1.getInstance();
System.out.println("instance1 = " + instance1);
System.out.println("instance2 = " + instance2);
Singleton2 instance3 = Singleton2.getInstance();
Singleton2 instance4 = Singleton2.getInstance();
System.out.println("instance3 = " + instance3);
System.out.println("instance4 = " + instance4);
}
//测试结果
instance1 = com.zjj.learn.designmodel.work.singleton.Singleton1@7b23ec81
instance2 = com.zjj.learn.designmodel.work.singleton.Singleton1@7b23ec81
instance3 = com.zjj.learn.designmodel.work.singleton.Singleton2@5f184fc6
instance4 = com.zjj.learn.designmodel.work.singleton.Singleton2@5f184fc6
更多单例模式的细节请查看:里面对单例模式有更多详细的说明