在Java中,实现单例模式主要有几种方式:懒汉式、饿汉式、双重检查锁定、静态内部类和枚举。每种方式都有其特点和适用场景。
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. 懒汉式(线程安全)
通过同步方法保证线程安全,但每次访问时都需要同步,会影响性能。
java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
4. 双重检查锁定(DCL)
双重检查锁定既保证了线程安全,又避免了每次访问时的性能损失。
java
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
5. 静态内部类
使用静态内部类的方式实现懒加载,且由JVM保证线程安全。
java
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
6. 枚举
使用枚举的方式是实现单例的最佳方法,不仅能避免多线程同步问题,还能防止反序列化重新创建新的对象。
java
// 实现枚举单例
public enum Singleton {
INSTANCE; // 唯一的枚举实例
// 枚举类中可以包含成员变量、方法等
private int value;
// 可以定义自己需要的操作,如设置、获取枚举实例的状态等
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
// 还可以定义其他方法
public void show() {
System.out.println("This is an enum singleton method.");
}
}
// 使用枚举单例
public class TestSingleton {
public static void main(String[] args) {
Singleton singleton = Singleton.INSTANCE;
singleton.setValue(1);
System.out.println(singleton.getValue());
singleton.show();
}
}