Java之单例模式

Java之单例模式

    • 前言
    • 1.概念
    • 2.基本用法
    • 3.饿汉式和懒汉式
    • 4.饿汉模式 vs 懒汉模式
    • 5.常见应用场景
    • 6.总结

前言

学习java的过程中,单例模式是一个比较重要的知识点,我们一起来学习一下吧!

1.概念

单例模式(Singleton Pattern)是一种创建型设计模式,其主要目标是确保一个类只有一个实例,并提供一个全局访问点来访问该实例。当实例需要在整个应用程序中被共享,单例模式是一个好的选择。

2.基本用法

单例模式的类需要满足三个条件:
1)定义一个私有(private)的构造方法
2)定义一个私有(private)的静态(static)实例变量
3)提供一个公共(public)的静态(static)方法,返回静态实例变量

3.饿汉式和懒汉式

单例模式一般分为饿汉式单例模式和懒汉式单例模式

// 饿汉式单例模式
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {
        // 私有构造方法
    }

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

//懒汉式单例模式(双重检查写法)
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {
        // 私有构造方法
    }

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

4.饿汉模式 vs 懒汉模式

在饿汉式单例模式中,实例在类加载时就已经创建,因此保证了线程安全。但是,这样的实现方式可能会导致资源浪费,因为无论是否需要使用该实例,都会在类加载时创建。

public class Singleton {
    // 私有静态实例变量,在类加载时就已经创建
    private static final Singleton instance = new Singleton();

    // 私有构造方法,防止外部直接实例化
    private Singleton() {
        // 一些初始化操作
    }

    // 公有静态方法,用于获取实例
    public static Singleton getInstance() {
        return instance;
    }
}

在懒汉式单例模模式中没有通过实例变量直接创建,而是把创建对象的语句写在getInstance方法中,这种模式节省了资源,但造成了线程不安全问题,实际应用中通常使用双重检查写法

//一般写法
public class Singleton {
    private static Singleton instance;

    // 私有构造方法
    private Singleton() {
        // 一些初始化操作
    }

    // 公有静态方法,用于获取实例
    public static Singleton getInstance() {
       
                if (instance == null) {
                    instance = new Singleton();
        }
        return instance;
    }
}


//双重检查
public class Singleton {
    // 使用volatile关键字保证可见性和禁止指令重排序
    private static volatile Singleton instance;

    // 私有构造方法
    private Singleton() {
        // 一些初始化操作
    }

    // 公有静态方法,用于获取实例
    public static Singleton getInstance() {
        // 第一次检查
        if (instance == null) {
            // 加锁,防止多线程并发创建实例
            synchronized (Singleton.class) {
                // 第二次检查,防止多个线程同时通过第一次检查,导致重复创建实例
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

5.常见应用场景

使用场景 描述
数据库连接池 保证整个应用程序只有一个数据库连接池实例,提高资源利用率。
日志记录器 创建唯一的日志记录器,确保日志信息集中管理,避免重复配置。
配置管理 提供全局访问点获取配置信息,确保应用程序中全局配置的一致性。
线程池 确保整个应用程序中只有一个线程池实例,协调线程的管理和执行。
缓存管理 创建全局的缓存管理器,确保缓存数据在应用程序中的一致性。

6.总结

特征 饿汉模式 懒汉模式
实例创建时机 在类加载时即创建实例。 在需要时才创建实例。
线程安全性 线程安全,因为在类加载时就创建了实例,保证了唯一性。 需要考虑线程安全性,通常使用双重检查锁定等机制保证在多线程环境中的安全创建。
性能影响 可能在程序启动时就创建实例,无需等待,但可能引发资源浪费。 只有在需要时才创建实例,可能导致在第一次访问时稍微耗时。
Lazy Loading 不支持延迟加载,实例在类加载时就创建。 支持延迟加载,实例在需要时才创建。
代码实现简单性 实现简单,无需考虑线程安全问题。 实现相对复杂,需要考虑多线程环境下的安全创建。
适用场景 适用于实例初始化消耗小、无额外资源需求、保证在程序启动时就创建实例的情况。 适用于实例初始化较为耗时、资源占用较大、能够延迟创建的情况。

你可能感兴趣的:(java,单例模式)