本文目录导读:

我来详细讲解Java懒汉单例模式的几种实操方式,从简单到优化的演进过程。
基础懒汉单例(线程不安全)
public class LazySingleton {
// 私有静态变量
private static LazySingleton instance;
// 私有构造方法
private LazySingleton() {
System.out.println("懒汉单例被创建");
}
// 公开获取实例方法
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
public void showMessage() {
System.out.println("Hello from Lazy Singleton!");
}
}
线程安全懒汉单例(synchronized方法)
public class ThreadSafeLazySingleton {
private static ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton() {}
// 使用synchronized保证线程安全
public static synchronized ThreadSafeLazySingleton getInstance() {
if (instance == null) {
instance = new ThreadSafeLazySingleton();
}
return instance;
}
}
双重检查锁定(推荐方式)
public class DoubleCheckedSingleton {
// volatile关键字禁止指令重排序
private static volatile DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {
// 防止反射攻击
if (instance != null) {
throw new RuntimeException("禁止反射创建实例");
}
System.out.println("DoubleCheckedSingleton 创建");
}
public static DoubleCheckedSingleton getInstance() {
// 第一次检查
if (instance == null) {
// 类级别锁
synchronized (DoubleCheckedSingleton.class) {
// 第二次检查
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
静态内部类方式(推荐方式)
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
System.out.println("StaticInnerClassSingleton 创建");
}
// 静态内部类
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
完整实操案例
public class LazySingletonDemo {
public static void main(String[] args) {
System.out.println("=== 懒汉单例测试 ===\n");
// 1. 单线程测试
System.out.println("=== 单线程测试 ===");
LazySingleton singleton1 = LazySingleton.getInstance();
LazySingleton singleton2 = LazySingleton.getInstance();
System.out.println("singleton1 == singleton2: " + (singleton1 == singleton2));
System.out.println();
// 2. 多线程测试双重检查锁定
System.out.println("=== 多线程测试 ===");
Runnable task = () -> {
DoubleCheckedSingleton instance = DoubleCheckedSingleton.getInstance();
System.out.println(Thread.currentThread().getName() + " 获取实例: " + instance.hashCode());
};
// 创建多个线程并发获取实例
Thread[] threads = new Thread[5];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(task, "线程-" + (i + 1));
threads[i].start();
}
// 等待所有线程完成
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 3. 展示静态内部类方式
System.out.println("\n=== 静态内部类测试 ===");
StaticInnerClassSingleton inner1 = StaticInnerClassSingleton.getInstance();
StaticInnerClassSingleton inner2 = StaticInnerClassSingleton.getInstance();
System.out.println("inner1 == inner2: " + (inner1 == inner2));
}
}
// 测试结果示例:
// === 懒汉单例测试 ===
//
// === 单线程测试 ===
// 懒汉单例被创建
// singleton1 == singleton2: true
//
// === 多线程测试 ===
// DoubleCheckedSingleton 创建
// 线程-1 获取实例: 123456789
// 线程-2 获取实例: 123456789
// 线程-3 获取实例: 123456789
// 线程-4 获取实例: 123456789
// 线程-5 获取实例: 123456789
//
// === 静态内部类测试 ===
// StaticInnerClassSingleton 创建
// inner1 == inner2: true
推荐使用场景
生产环境推荐方案
// 方案1:双重检查锁定(需要JDK5+)
public class SingletonA {
private static volatile SingletonA instance;
private SingletonA() {
if (instance != null) {
throw new RuntimeException("禁止反射");
}
}
public static SingletonA getInstance() {
if (instance == null) {
synchronized (SingletonA.class) {
if (instance == null) {
instance = new SingletonA();
}
}
}
return instance;
}
}
// 方案2:静态内部类(最简洁安全)
public class SingletonB {
private SingletonB() {}
private static class Holder {
static final SingletonB INSTANCE = new SingletonB();
}
public static SingletonB getInstance() {
return Holder.INSTANCE;
}
}
完整测试类
public class CompleteTest {
public static void main(String[] args) throws Exception {
// 验证单例
System.out.println("测试单例模式:");
// 验证双重检查锁定
DoubleCheckedSingleton d1 = DoubleCheckedSingleton.getInstance();
DoubleCheckedSingleton d2 = DoubleCheckedSingleton.getInstance();
System.out.println("双重检查锁定: " + (d1 == d2)); // true
// 验证静态内部类
StaticInnerClassSingleton s1 = StaticInnerClassSingleton.getInstance();
StaticInnerClassSingleton s2 = StaticInnerClassSingleton.getInstance();
System.out.println("静态内部类: " + (s1 == s2)); // true
}
}
- 双重检查锁定:使用
volatile防止指令重排序 - 静态内部类:利用类加载机制保证线程安全
- 防止反射:在构造方法中添加检查
- 懒加载:只有在调用
getInstance()时才创建实例
推荐使用静态内部类方式实现懒汉单例,既保证了线程安全,又实现了懒加载,代码简洁高效。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播