目录
饿汉式单例模式
懒汉式单例模式
Spring中的单例模式
关键差异对比
在Java和Spring中的应用场景
手写案例
单例模式是一种创建型设计模式,其核心在于确保一个类仅有一个实例,并提供一个全局访问点来获取该实例。下面将详细介绍饿汉式和懒汉式单例模式,以及它们在Java和Spring框架中的体现。
饿汉式单例模式
这种模式的特点是类加载时就创建实例,无需等待首次使用。它不存在线程安全问题,因为实例的创建是在类加载阶段完成的。
Java实现示例:
public class EagerSingleton {private static final EagerSingleton INSTANCE = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return INSTANCE;}
}
懒汉式单例模式
懒汉式单例模式是在首次使用时才创建实例。不过,在多线程环境下,如果没有合适的同步机制,就可能会创建多个实例。
非线程安全的Java实现示例:
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
线程安全的Java实现示例:
public class ThreadSafeLazySingleton {private static volatile ThreadSafeLazySingleton instance;private ThreadSafeLazySingleton() {}public static ThreadSafeLazySingleton getInstance() {if (instance == null) {synchronized (ThreadSafeLazySingleton.class) {if (instance == null) {instance = new ThreadSafeLazySingleton();}}}return instance;}
}
Spring中的单例模式
在Spring框架里,默认情况下,所有的bean都是以单例模式创建的,也就是在整个应用上下文中只存在一个实例。
Spring单例bean示例:
@Component
public class SpringSingleton {// Spring会自动管理这个bean的单例实例
}
获取Spring单例bean的方式:
@Autowired
private SpringSingleton springSingleton;
关键差异对比
维度 | 饿汉式 | 懒汉式(线程安全) |
实例创建时机 | 类加载时 | 首次调用时 |
线程安全性 | 安全 | 安全 |
优点 | 实现简单,无需考虑线程安全问题 | 延迟加载,节省资源 |
缺点 | 可能造成资源浪费 | 实现较为复杂,性能可能受影响 |
适用场景 | 实例创建成本低,且一定会被使用 | 实例创建成本高,或不一定会被使用 |
在Java和Spring中的应用场景
- Java中的应用:像日志记录器、数据库连接池这类需要全局唯一实例的场景,会用到单例模式。
- Spring中的应用:Spring框架默认将bean配置为单例,这样可以减少内存开销,同时保证状态管理的一致性。
理解单例模式的不同实现方式以及它们在Java和Spring中的应用,有助于设计出高效且线程安全的应用程序。
手写案例
public class Main { }// 单例模式 初始化bean// 饿汉式 单例初始化
// 在类首次加载时就进行初始化 不需要考虑线程安全问题
class Hungrybean{private static final Hungrybean INSTANCE = new Hungrybean();public static Hungrybean getInstance() {return INSTANCE;}
}// 懒汉式 单例初始化
// 在使用时再进行初始化 可能存在线程安全问题
class Lazybean{private static Lazybean INSTANCE ;public static Lazybean getInstance() {if(INSTANCE==null){INSTANCE=new Lazybean();}return INSTANCE;}
}// 锁机制 修复了懒汉是的线程安全问题
class ThreadSafeLazybean{private static ThreadSafeLazybean INSTANCE;public static ThreadSafeLazybean getInstance(){if(INSTANCE==null){synchronized (ThreadSafeLazybean.class){if (INSTANCE==null){INSTANCE=new ThreadSafeLazybean();}return INSTANCE;}}}
}