单例模式是一种设计模式,它确保一个类只有一个实例并提供全局访问点。单例模式有两种实现方式:懒汉式和饿汉式。懒汉式指的是在第一次访问时才创建唯一实例,这种实现方式在实例创建开销较大或者实例使用不频繁时,可以减少不必要的资源开销。但在多线程环境下,需要使用同步锁来确保线程安全。饿汉式指的是在类加载时就创建唯一实例,这种实现方式能保证线程安全,因为类加载时的操作是线程安全的。由于实例在类加载时就创建,无论是否需要使用都会占用资源,可能导致资源浪费 。
在编程中,我们经常需要确保某个类只有一个实例存在,这种情况下,单例模式(Singleton Pattern)就成为了一种非常实用的设计模式,它保证了一个类仅有一个对象,并提供了一个全局访问点来获取这个唯一的对象,本文将详细介绍单例模式的定义、实现以及优缺点。
1. 单例模式的定义
单例模式是一种创建型设计模式,它保证一个类仅有一个实例,并提供一个访问该实例的全局访问点,单例模式就是让一个类在整个程序运行期间,只能有一个实例存在。
2. 单例模式的实现
2.1 饿汉式(静态常量)
饿汉式是在类加载时就完成了初始化,避免了线程同步问题,如果饿汉式中的初始化操作非常耗时或者资源消耗较大,那么这种方式就不太适用了。
public class Singleton { // 在类加载时就完成了初始化,避免了线程同步问题 private static final Singleton instance = new Singleton(); // 构造方法私有化,防止外部创建实例 private Singleton() {} // 提供一个全局访问点来获取这个唯一的对象 public static Singleton getInstance() { return instance; } }
2.2 懒汉式(线程安全,同步方法)
懒汉式是在第一次调用getInstance()方法时才进行初始化,这样可以避免在启动时就进行初始化导致的性能问题,为了保证线程安全,我们需要使用synchronized关键字对getInstance()方法进行同步。
public class Singleton { // 将构造方法设为私有,防止外部创建实例 private static volatile Singleton instance; // 提供一个全局访问点来获取这个唯一的对象 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2.3 双重检查(推荐)
双重检查锁定(Double-Checked Locking)机制既保证了线程安全,又减少了同步开销,它通过在每次调用getInstance()方法时先判断是否已经创建了实例,如果没有则进行同步初始化,当实例被创建后,将其设置为volatile类型,以确保所有线程都能看到最新的实例状态。
public class Singleton { // 将构造方法设为私有,防止外部创建实例 private static volatile Singleton instance; // 通过双重检查锁定机制实现线程安全和性能优化 public static Singleton getInstance() { if (instance == null) { // 这里进行了同步初始化操作,减少了同步开销 synchronized (Singleton.class) { // 对getInstance()方法进行同步,保证线程安全 if (instance == null) { // 这里是一个空循环,不会执行多次,减少了CPU消耗 instance = new Singleton(); } } } return instance; } }
3.