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单例模式我只推荐两种
基础教程推荐
- 深入理解约瑟夫环的数学优化方法 2024-03-07
- SpringBoot接收参数使用的注解实例讲解 2023-04-17
- 强烈推荐MyBatis 三种批量插入方式的比较 2023-03-15
- 一文带你深入了解Java TreeMap 2023-05-14
- javaWeb连接数据库实现简单登陆注册功能的全过程 2023-01-13
- Java实现全排列的三种算法详解 2023-01-18
- Java实现Excel表单控件的添加与删除 2022-11-16
- Java LinkedHashMap深入分析源码 2023-07-01
- Mybatis中使用in()查询的方式详解 2023-04-17
- 使用Mybatis-Plus时的SqlSessionFactory问题及处理 2023-08-07