supplier可实现延迟加载与懒汉单例:封装创建逻辑,首次get()时初始化,避免提前开销;结合volatile与双重检查可线程安全单例;配合optional.orelseget可条件创建;封装lazy工具类进一步统一懒加载语义。

直接用 Supplier 实现延迟加载和懒汉式单例,核心是把“创建动作”推迟到第一次调用时才执行,避免启动就初始化、浪费资源。它比手写双重检查锁更轻量,也比静态内部类更灵活,尤其适合依赖运行时参数或外部状态的场景。
延迟加载高成本对象
当对象构造开销大(比如读取大配置文件、建立远程连接、解析复杂 JSON),不要在字段声明或构造器里直接 new。
- 错误做法:类一实例化就执行,不管后续是否用到
private final DatabaseClient client = createHeavyClient(); - 正确做法:用 Supplier 封装创建逻辑,只在
get()被调用时才触发private final Supplier<databaseclient> clientSupplier = () -> createHeavyClient();</databaseclient> - 使用时只需:
DatabaseClient client = clientSupplier.get();—— 第一次调用才初始化,之后每次都是复用已创建的对象(注意:Supplier 本身不缓存,需自行处理)
实现线程安全的懒汉式单例
如果希望 Supplier 创建的对象全局唯一且只初始化一次,可结合 volatile + 双重校验封装成带缓存的 Supplier:
- 定义一个 volatile 缓存字段:
private volatile DatabaseClient cachedClient; - 构造 Supplier 时内嵌懒加载逻辑:
Supplier<databaseclient> singletonSupplier = () -> {<br> if (cachedClient == null) {<br> synchronized (this) {<br> if (cachedClient == null) {<br> cachedClient = createHeavyClient();<br> }<br> }<br> }<br> return cachedClient;<br>};</databaseclient> - 这样既复用了 Supplier 的函数式表达力,又保证了线程安全与仅初始化一次
配合 Optional 做条件性默认值
在需要 fallback 场景下(如从缓存取不到时再加载),Supplier 能避免无谓创建:
- 危险写法(每次都 new):
user.orElse(new ExpensiveUser()) - 推荐写法(仅为空时才创建):
user.orElseGet(() -> buildDefaultUser())或user.orElseGet(this::buildDefaultUser) - 特别适合高频调用、循环体或批量处理,实测可减少 30%~50% 的无效对象分配
封装通用懒加载容器(Lazy)
可抽象出一个泛型工具类,统一管理延迟初始化逻辑:
public class Lazy<t> { private final Supplier<t> supplier; private volatile T value; public Lazy(Supplier<t> supplier) { this.supplier = supplier; } public T get() { if (value == null) { synchronized (this) { if (value == null) { value = supplier.get(); } } } return value; } }</t></t></t>- 使用:
Lazy<config> config = new Lazy(this::loadConfig); Config c = config.get();</config> - 该结构天然支持懒汉语义,且线程安全,无需额外引入 Guava 或 Spring











