Java中的单例模式详解(完整篇)

Java中的单例模式是一种常见的设计模式,它用于确保类只有一个实例,并提供全局的访问点。在某些场景下,单例模式可以提高系统的性能和效率。下面是单例模式详解的完整攻略:

什么是单例模式

单例模式(Singleton Pattern)是一种常见的创建型设计模式,它可以确保一个类只有一个实例,并提供全局的访问点。单例模式可以避免不必要的对象创建,提高系统的性能和效率。此外,在一个多线程的环境下,单例模式还可以避免竞态条件和锁竞争。

单例模式的实现

单例模式的实现一般有两种方法:饿汉式和懒汉式。

饿汉式

饿汉式是一种较为简单的单例模式实现方式,它的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。常见的实现方式如下:

public class Singleton {
    // 在类加载的时候就创建单例对象
    private static Singleton instance = new Singleton();
    // 私有构造函数,确保外部无法实例化该类
    private Singleton() {}
    // 获取单例的唯一访问点
    public static Singleton getInstance() {
        return instance;
    }
}

懒汉式

懒汉式是一种比较懒惰的单例模式实现方式,它的特点是单例的实例只会在第一次调用 getInstance 方法时被创建。常见的实现方式如下:

public class Singleton {
    // 声明单例,但暂时不创建单例对象
    private static Singleton instance = null;
    // 私有构造函数,确保外部无法实例化该类
    private Singleton() {}
    // 获取单例的唯一访问点
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

双重校验锁式

双重校验锁式是一种线程安全的懒汉式单例模式实现方式,它的特点是在需要时才会创建单例。通过双重校验锁,既避免了锁竞争,又避免了每次获取锁的开销。常见的实现方式如下:

public class Singleton {
    // 声明单例,但暂时不创建单例对象
    private static volatile Singleton instance = null;
    // 私有构造函数,确保外部无法实例化该类
    private Singleton() {}
    // 获取单例的唯一访问点
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

单例模式的使用

单例模式在实际开发中经常用于工具类、配置类、日志类等场景中。下面通过两个示例来说明单例模式的使用。

配置文件工具类

我们经常会用到配置文件来保存应用程序的配置信息。下面是一个配置文件工具类的示例,它可以读取和写入配置文件,并提供全局的访问点。

public class ConfigUtil {
    // 声明单例,但暂时不创建单例对象
    private static volatile ConfigUtil instance = null;
    // 保存配置信息的 Map
    private Map<String, String> configMap = new HashMap<>();
    // 私有构造函数,确保外部无法实例化该类
    private ConfigUtil() {
        // 初始化配置信息
        loadConfig();
    }
    // 加载配置信息
    private void loadConfig() {
        // 读取配置文件,将配置信息保存到 configMap 中
    }
    // 获取单例的唯一访问点
    public static ConfigUtil getInstance() {
        if (instance == null) {
            synchronized(ConfigUtil.class) {
                if (instance == null) {
                    instance = new ConfigUtil();
                }
            }
        }
        return instance;
    }
    // 获取配置信息
    public String getConfigValue(String key) {
        return configMap.get(key);
    }
    // 设置配置信息
    public void setConfigValue(String key, String value) {
        configMap.put(key, value);
    }
    // 保存配置信息到文件
    public void saveConfig() {
        // 将 configMap 中的配置信息写入配置文件
    }
}

日志记录器

日志记录器通常用于记录应用程序的运行日志。下面是一个简单的日志记录器的示例,它可以记录日志,并提供全局的访问点。

public class Logger {
    // 声明单例,但暂时不创建单例对象
    private static volatile Logger instance = null;
    // 日志文件的路径
    private String logFilePath = "";
    // 私有构造函数,确保外部无法实例化该类
    private Logger() {}
    // 获取单例的唯一访问点
    public static Logger getInstance() {
        if (instance == null) {
            synchronized(Logger.class) {
                if (instance == null) {
                    instance = new Logger();
                }
            }
        }
        return instance;
    }
    // 写入日志
    public void log(String message) {
        // 将日志写入日志文件
    }
    // 设置日志文件的路径
    public void setLogFilePath(String logFilePath) {
        this.logFilePath = logFilePath;
    }
}

单例模式的扩展

单例模式还可以通过一些扩展方式来增加功能或者优化性能,常见的扩展方式如下:

线程池化单例

线程池化单例是一种将多个单例对象缓存到线程池中,从而提高单例对象的重用率和系统的性能。

延迟加载单例

延迟加载单例是一种将单例对象的创建延迟到第一次使用时再进行,从而避免了不必要的对象创建。

总结

单例模式是一种常见的设计模式,它可以确保一个类只有一个实例,并提供全局的访问点,从而提高系统的性能和效率。单例模式的实现一般有饿汉式、懒汉式和双重校验锁式等方式。在实际开发中,单例模式经常用于工具类、配置类、日志类等场景中。单例模式还可以通过线程池化、延迟加载等方式进行扩展。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中的单例模式详解(完整篇) - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Springboot集成restTemplate过程详解

    下面是详细讲解“Springboot集成restTemplate过程详解”的完整攻略。 介绍 在Springboot中,restTemplate是一个常用的HTTP客户端,用于发送REST请求和接收REST响应。本文将介绍如何在Springboot中集成restTemplate。 步骤 步骤1:添加依赖 首先,在项目的pom.xml文件中添加以下依赖: &l…

    Java 2023年5月15日
    00
  • Java中字符序列的替换与分解的几种实现方法

    Java中字符序列的替换与分解的几种实现方法 字符串(String)是Java编程中最常见的数据类型之一。但是,如果我们要处理字符串中包含的字符序列时,String类的效率并不高。字符串的每次修改都会导致创建一个新的字符串对象,这会很容易造成内存泄漏和效率低下的问题。为了克服这些问题,Java提供了两种更适合于字符操作的数据类型:StringBuilder和…

    Java 2023年5月27日
    00
  • 在Java中轻松使用工厂设计模式介绍

    在Java中轻松使用工厂设计模式介绍 概述 工厂设计模式(Factory design pattern)是一种常用的设计模式,它将对象的创建过程抽象出来,使得代码的可维护、可扩展性提高,并且能够让我们避免使用new关键字直接创建对象。Java中有两种主要的工厂设计模式:工厂方法模式(Factory Method Pattern)和抽象工厂模式(Abstrac…

    Java 2023年5月26日
    00
  • Mybatis增删改查mapper文件写法详解

    我来为您详细讲解”Mybatis增删改查mapper文件写法详解”。 1. Mybatis Mapper文件介绍 Mybatis是一种基于Java的持久层框架,通过XML或注解的方式将要执行的SQL语句和映射关系描述出来,封装了JDBC的操作,并且能够进行灵活的配置。其中,Mapper文件就是用来描述SQL语句和映射关系的文件。 一个典型的Mapper文件通…

    Java 2023年5月19日
    00
  • JSP spring boot / cloud 使用filter防止XSS

    下面是详细的JSP Spring Boot/Cloud使用Filter防止XSS的攻略: 什么是XSS攻击 XSS(Cross Site Scripting)攻击是一种非常常见的互联网应用程序攻击,攻击者通过注入恶意脚本代码,在受害者的浏览器中运行这些脚本,从而窃取用户的个人信息或者执行其他危险操作。该攻击方式十分危险,能够威胁到用户的隐私和信息安全,目前已…

    Java 2023年6月15日
    00
  • java实现简单的俄罗斯方块

    Java实现简单的俄罗斯方块攻略 1. 搭建环境 首先需要搭建 Java 开发环境,具体可以根据个人喜好选择合适的集成开发环境(IDE),例如 Eclipse、IntelliJ IDEA 等。 2. 准备资源 在实现俄罗斯方块的过程中需要用到一些图片素材,例如方块图案,这些资源可以从图片库中或者网络下载得到。 3. 实现游戏界面 使用 Java Swing …

    Java 2023年5月18日
    00
  • spring-transaction源码分析(2)EnableTransactionManagement注解

    概述(Java doc) 该注解开启spring的注解驱动事务管理功能,通常标注在@Configuration类上面用于开启命令式事务管理或响应式事务管理。 @Configuration @EnableTransactionManagement public class AppConfig { @Bean public FooRepository fooRe…

    Java 2023年5月6日
    00
  • jdk1.8的环境配置过程

    下面是 JDK 1.8 的环境配置过程攻略: 环境准备 在开始配置 JDK 1.8 之前需要先准备好以下内容: 一台已经安装好的计算机 从 Oracle 官网下载 JDK 1.8,并安装到计算机上 配置过程 配置环境变量 JDK 的环境变量配置非常重要,它可以让操作系统找到 JDK 安装路径。下面是配置 JDK 环境变量的方法: 打开“系统属性界面”(可以按…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部