目录
一、饿汉式单例模式
二、懒汉式单例模式
三、最完美的单例模式写法
单例模式一般分为饿汉式与懒汉式(类似于懒加载)。饿汉式会在类加载时即刻创建实例对象,线程安全;懒汉式由于是在调用时才创建,所以需要考虑线程安全。下面来看看各种单例模式的实现代码:
一、饿汉式单例模式
一般简单的实现可以采用饿汉式单例模式即可,满足大多数需求。
/**
* @author Dragon Wu
* @since 2023/1/18 15:12
* 饿汉式单例模式
* 线程安全
*/
public class MyObj01 {
private static final MyObj01 INSTANCE = new MyObj01();
private MyObj01() {
}
public static MyObj01 getINSTANCE() {
return INSTANCE;
}
public static void main(String[] args) {
MyObj01 obj1 = getINSTANCE();
MyObj01 obj2 = getINSTANCE();
System.out.println(obj1 == obj2);
}
}
运行结果:可以看到两个实例对象的地址相同为单例对象
二、懒汉式单例模式
通过懒加载能节省很多不必要的性能开销
第一种,通过JVM来管控线程安全的实现,静态内部类的单例模式,一下方式可谓是完美的单例实现之一。
/**
* @author Dragon Wu
* @since 2023/1/18 15:59
* 单例模式最好的实现格式之一
* 懒汉式 通过静态内部类来实现单例模式 懒加载
* 单例可由JVM来保证线程安全 推荐使用
*/
public class MyObj02 {
private static class MyObj02Inner {
private static final MyObj02 INSTANCE = new MyObj02();
}
private MyObj02() {
}
public static MyObj02 getINSTANCE() {
return MyObj02Inner.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(MyObj02.getINSTANCE().hashCode());
}).start();
}
}
}
运行效果:可以看到对象100个线程调用的单例对象都是同一个,由于未通过锁的方式,性能也不会受锁影响。
三、最完美的单例模式写法
java大佬Effective Java书籍作者写的一种单例模式代码方式,完美中的完美,不仅解决线程安全和性能方面的问题,还避免了反序列化的问题,具体代码如下:
/**
* @author Dragon Wu
* @since 2023/1/18 16:14
* 完美中的完美
* 懒汉式
* 解决线程安全与防止反序列化
*/
public enum MyObj03 {
INSTANCE;
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(MyObj03.INSTANCE.hashCode());
}).start();
}
}
}
运行结果:利用枚举类的特性可以完美实现单例设计模式
以上三种设计模式均可解决单例问题,可通过实际问题,选择最合适的解决方案。