Java单例模式是一种设计模式,它确保一个类在任何时间内只有一个实例,并提供一种全局访问该实例的方式。单例模式在许多场景中都很有用,例如线程池、数据库连接池、日志工具等。
Java单例模式是一种设计模式,它确保一个类在任何时间内只有一个实例,并提供一种全局访问该实例的方式。单例模式在许多场景中都很有用,例如线程池、数据库连接池、日志工具等。
在Java的单例模式实现中,有很多方法,但是只有少数几种方法被广泛认为是最有效、最稳定、最可靠的。本文将介绍这些最流行的两种Java单例模式实现,同时详细讲解它们的优点和缺点。
饿汉式单例模式
饿汉式单例模式是指在类加载的时候就创建唯一一个实例,这种方法最简单,但是也有一些不足之处。
下面是饿汉式单例模式的Java代码实现:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
饿汉式单例模式的优点是它的实现非常简单,线程安全,并且没有多线程问题。它还避免了懒汉式单例模式的同步问题。
饿汉式单例模式的缺点是它可能会在系统启动时创建实例,如果实例很大或创建时间很长,系统启动时间会变长。饿汉式单例模式还会创建不必要的实例,当实例用不到时会浪费系统资源。
懒汉式单例模式
懒汉式单例模式是指在第一次调用getInstance()方法时才创建类的唯一实例,这种方法可以避免在系统启动时创建不必要的实例,但是也有一些不足之处。
下面是懒汉式单例模式的Java代码实现:
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;
}
}
懒汉式单例模式的优点是在第一次调用getInstance()方法时才创建实例,避免了不必要的实例创建,提高了系统性能。
懒汉式单例模式及加锁的优化能够实现线程安全。由于需要在 getInstance() 方法上设置同步锁,所以在多线程环境下会有一些影响系统性能的问题。为了避免这种同步锁问题,我们可以使用双检锁 DCL (Double-Check Locking)的方式来实现。
懒汉式单例模式的缺点是这种方法的实现比较复杂,并且在多线程环境下性能会受到影响。此外,在某些情况下,由于JVM和编译器的处理顺序问题,它可能导致错误的结果。
示例说明
假设有一个参数配置单例类:
public class Config {
private Properties props = new Properties();
public void load(String filePath) {
InputStream in = getClass().getResourceAsStream(filePath);
try {
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public String get(String key) {
return props.getProperty(key);
}
}
我们可以使用饿汉式单例模式来实现该类的单例,以确保在系统启动时加载配置信息:
public class ConfigLoader {
private static final Config instance = new Config();
private ConfigLoader() {
instance.load("/config.properties");
}
public static Config getInstance() {
return instance;
}
}
我们也可以使用懒汉式单例模式来实现该类的单例,以避免在系统启动时加载不必要的实例:
public class ConfigLoader {
private static volatile Config instance = null;
private ConfigLoader() {
}
public static Config getInstance() {
if (instance == null) {
synchronized (ConfigLoader.class) {
if (instance == null) {
instance = new Config();
instance.load("/config.properties");
}
}
}
return instance;
}
}
以上是Java单例模式的基础实现,但是单例模式还有其他的变体,例如枚举单例模式和静态内部类单例模式等。开发人员需要根据项目需求选择合适的单例模式实现方式。
本文标题为:为何Java单例模式我只推荐两种


基础教程推荐
- ConcurrentHashMap 存储结构源码解析 2023-06-17
- java – com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:无法创建与数据库服务器的连接 2023-10-31
- Mybatis的动态Sql组合模式详情 2023-04-17
- Spring Boot详解配置文件有哪些作用与细则 2023-03-15
- JSP 多个文件打包下载代码 2023-12-24
- JSP中九大内置对象和四种属性范围详解 2023-08-01
- vue 请求后台数据的实例代码 2024-01-16
- java – 奇怪的Oracle连接URL 2023-11-02
- Java常用类之System类的使用指南 2023-03-11
- 图解Java经典算法希尔排序的原理与实现 2023-05-14