单例模式:手写实现中的那些坑与技巧

一、什么是单例模式?
单例模式(Singleton Pattern)是一种常用的软件设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。单例模式在Java编程中应用广泛,特别是在资源管理、配置管理等场景中。
二、手写单例模式
1. 懒汉式
懒汉式单例模式是指在使用实例之前,才去创建其实例。以下是一个简单的懒汉式单例模式实现:
```java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
```
这种实现方式简单易理解,但存在线程安全问题。当多线程访问`getInstance()`方法时,由于`instance`对象还未创建,可能会出现多个线程同时进入`if`语句块,导致创建多个实例。
2. 饿汉式
饿汉式单例模式是在类加载时就创建好实例。以下是一个简单的饿汉式单例模式实现:
```java
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
```
这种实现方式简单,且线程安全,但缺点是如果类被加载了,但实例没有被使用,会浪费资源。
3. 双重校验锁
双重校验锁是一种解决懒汉式线程安全问题的方式。以下是一个双重校验锁的实现:
```java
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;
}
}
```
双重校验锁通过在`if`语句块外加锁,确保只创建一个实例。这种方式兼顾了懒加载和线程安全。
4. 静态内部类
静态内部类是一种更简洁、高效的实现单例模式的方式。以下是一个静态内部类的实现:
```java
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
静态内部类实现单例模式利用了类加载机制保证线程安全。当调用`getInstance()`方法时,才会加载内部类`SingletonHolder`,此时`INSTANCE`对象被创建。
5. 枚举
枚举实现单例模式是Java提供的一种最简单、最安全的实现方式。以下是一个枚举实现单例模式的示例:
```java
public enum Singleton {
INSTANCE;
public void doSomething() {
// ...
}
}
```
枚举实现单例模式利用了枚举类是单例的特性,确保只有一个实例。同时,枚举类型天然具备序列化机制,保证序列化后反序列化仍然是单例。
三、总结
单例模式在Java编程中应用广泛,掌握手写单例模式的实现方法对于开发者来说至关重要。本文介绍了懒汉式、饿汉式、双重校验锁、静态内部类和枚举五种手写单例模式的方式,每种方式都有其优缺点。在实际应用中,开发者应根据具体需求选择合适的单例模式实现方式。





