单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点来获取该实例。单例模式的目的是限制一个类只能创建一个对象,以便在整个应用程序中共享该对象的状态和行为。
在单例模式中,类会提供一个静态方法或静态变量来获取单例实例。这个静态方法会检查是否已经存在实例,如果存在则返回该实例,如果不存在则创建一个新的实例。同时,为了防止通过其他方式创建实例,单例模式的构造函数通常会被设置为私有的,这样外部无法直接实例化该类。
单例模式广泛应用于需要共享资源、控制资源访问以及避免重复创建对象等场景。例如,数据库连接池、日志记录器、配置文件管理器等都可以使用单例模式来实现。
通过单例模式,我们可以确保在整个应用程序中使用相同的实例,避免了资源的浪费和不一致性的问题。
这种写法在第一次使用时才创建实例。示例代码如下:
public class Singleton {
private static Singleton instance;
private Singleton() {
// 私有构造函数,防止外部实例化
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这种写法简单直观,但在多线程环境下可能存在线程安全问题,需要使用 synchronized 关键字来解决。
这种写法在懒汉式的基础上进行了优化,减少了加锁的开销。示例代码如下:
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;
}
}
使用 volatile 关键字和双重检查的方式,可以在多线程环境下保证线程安全。
这种写法在类加载时就创建实例,不存在线程安全问题。示例代码如下:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// 私有构造函数,防止外部实例化
}
public static Singleton getInstance() {
return instance;
}
}
这种写法简单直接,但可能会造成资源浪费,因为实例在类加载时就被创建,即使后续并没有被使用到。
public class SingletonObj {
//内部类使用枚举
private enum SingletonEnum {
INSTANCE;
private SingletonObj singletonObj;
//在枚举类的构造器里初始化singletonObj
SingletonEnum() {
singletonObj = new SingletonObj();
}
private SingletonObj getSingletonObj() {
return singletonObj;
}
}
//对外部提供的获取单例的方法
public static SingletonObj getInstance() {
//获取单例对象,返回
return SingletonEnum.INSTANCE.getSingletonObj();
}
}
单例模式比较简单,我们只要确保一个类只有一个实例,并提供全局访问点来获取该实例就行了。在spring源码中是放到一个唯一的且并发安全的Map中,每次使用都是从这个唯一的map中获取对象。