10 Java设计模式之单例模式

在前一篇中,我们探讨了Java 8的新特性,特别是Optional类,它帮助我们有效地处理可能为null的值,从而减小了出现NullPointerException的风险。而在本篇文章中,我们将深入理解Java设计模式中的单例模式。这是一个非常重要的设计模式,常用于确保某个类只有一个实例,并提供全局访问点。

什么是单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点。这个模式通常用于控制对共享资源的访问,例如数据库连接、线程池等。

在Java中,单例模式的实现有多种方式,下面我们将介绍最常用的几种。

单例模式的实现方式

1. 饿汉式单例

饿汉式单例是在类加载时立即实例化Singleton类的实例。当这个类被使用时,实例已存在。

实现代码

1
2
3
4
5
6
7
8
9
10
11
public class Singleton {
private static final Singleton INSTANCE = new Singleton();

private Singleton() {
// 私有构造函数,防止外部实例化
}

public static Singleton getInstance() {
return INSTANCE;
}
}

使用示例

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();

System.out.println(singleton1 == singleton2); // 输出 true
}
}

2. 懒汉式单例

懒汉式单例在需要时才创建实例。为了避免多线程环境下的竞争,通常会使用synchronized关键字来确保线程安全。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class LazySingleton {
private static LazySingleton instance;

private LazySingleton() {
// 私有构造函数,防止外部实例化
}

public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}

使用示例

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
LazySingleton lazySingleton1 = LazySingleton.getInstance();
LazySingleton lazySingleton2 = LazySingleton.getInstance();

System.out.println(lazySingleton1 == lazySingleton2); // 输出 true
}
}

3. 双重检查锁定单例

为了提高懒汉式单例的性能,可以使用双重检查锁定(Double-Check Locking)进行优化。这样,只有在实例为空时,才会 synchronized,以降低了性能开销。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DoubleCheckSingleton {
private static volatile DoubleCheckSingleton instance;

private DoubleCheckSingleton() {
// 私有构造函数,防止外部实例化
}

public static DoubleCheckSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckSingleton.class) {
if (instance == null) {
instance = new DoubleCheckSingleton();
}
}
}
return instance;
}
}

使用示例

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
DoubleCheckSingleton doubleCheckSingleton1 = DoubleCheckSingleton.getInstance();
DoubleCheckSingleton doubleCheckSingleton2 = DoubleCheckSingleton.getInstance();

System.out.println(doubleCheckSingleton1 == doubleCheckSingleton2); // 输出 true
}
}

4. 静态内部类单例

通过一个静态内部类来实现单例模式,利用JVM的类加载机制来达到懒加载和线程安全的效果。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
// 私有构造函数,防止外部实例化
}

private static class Holder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}

public static StaticInnerClassSingleton getInstance() {
return Holder.INSTANCE;
}
}

使用示例

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
StaticInnerClassSingleton singleton1 = StaticInnerClassSingleton.getInstance();
StaticInnerClassSingleton singleton2 = StaticInnerClassSingleton.getInstance();

System.out.println(singleton1 == singleton2); // 输出 true
}
}

总结

单例模式在Java中具有广泛的应用场景,它可以有效地控制实例的创建,节省资源并简化管理。在实际使用中,应根据具体的需求选择合适的单例模式实现方式。接下来,我们将对比单例模式与工厂模式,以更好地理解这两种设计模式在实际开发中的应用。

通过掌握单例模式,您将能够在需要确保某个类只有一个实例时做出正确的设计决策,为接下来的工厂模式打下良好的基础。

10 Java设计模式之单例模式

https://zglg.work/java-one/10/

作者

IT教程网(郭震)

发布于

2024-08-10

更新于

2024-08-10

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论