在前一篇中,我们探讨了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); } }
|
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); } }
|
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); } }
|
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); } }
|
总结
单例模式在Java中具有广泛的应用场景,它可以有效地控制实例的创建,节省资源并简化管理。在实际使用中,应根据具体的需求选择合适的单例模式实现方式。接下来,我们将对比单例模式与工厂模式,以更好地理解这两种设计模式在实际开发中的应用。
通过掌握单例模式,您将能够在需要确保某个类只有一个实例时做出正确的设计决策,为接下来的工厂模式打下良好的基础。