浏览量:86 最近编辑于:2025-02-20 18:31:13
在 Java 中,单例模式(Singleton Pattern)是一种常用的设计模式,用于确保一个类在整个应用程序中只有一个实例,并提供全局访问点。以下是几种常见的单例模式实现方式:
# 1. 饿汉式(线程安全,类加载时初始化)
饿汉式在类加载时就创建实例,线程安全,但可能会造成资源浪费(如果实例未被使用)。
```java
public class Singleton {
// 静态变量,类加载时初始化
private static final Singleton INSTANCE = new Singleton();
// 私有构造方法,防止外部实例化
private Singleton() {}
// 提供全局访问点
public static Singleton getInstance() {
return INSTANCE;
}
}
```
优点:
简单易实现。
线程安全。
缺点:
类加载时就初始化实例,可能会造成资源浪费。
## 2. 懒汉式(线程不安全,延迟加载)
懒汉式在第一次调用时才创建实例,但默认实现线程不安全。
```java
public class Singleton {
// 静态变量,延迟初始化
private static Singleton instance;
// 私有构造方法
private Singleton() {}
// 提供全局访问点
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // 非线程安全
}
return instance;
}
}
```
## 3. 懒汉式(线程安全,使用 synchronized)
通过在 getInstance 方法上加锁,确保线程安全。
```java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
```
## 4. 双重检查锁(线程安全,性能较优)
双重检查锁通过减少加锁范围,提高性能,同时保证线程安全。
```java
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.静态内部类(线程安全,延迟加载)
利用类加载机制实现线程安全和延迟加载。
```java
public class Singleton {
private Singleton() {}
// 静态内部类,只有在调用 getInstance 时才会加载
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
```
总结
实现方式 是否线程安全 是否延迟加载 优点 缺点
饿汉式 是 否 简单易实现,线程安全 类加载时初始化,可能浪费资源
懒汉式(非线程安全) 否 是 延迟加载 线程不安全
懒汉式(线程安全) 是 是 延迟加载,线程安全 性能较低
双重检查锁 是 是 延迟加载,性能较高 实现稍复杂
静态内部类 是 是 延迟加载,线程安全,简单实现 无法传递参数
枚举单例 是 否 线程安全,防止反序列化和反射攻击 不支持延迟加载
ThreadLocal 单例 是 是 每线程独立实例,适合线程隔离场景 不是真正的全局单例