JJava 知识库
JAVA INTERVIEW

高频面试题

Java集合进阶约 2 分钟

配置热更新时,怎么保证业务线程看到的是一份完整配置,而不是更新到一半的集合?

参考回答约 2 分钟 · 口语表达
我的判断

配置热更新不要在原 Map 上逐项修改,而是完整构建并校验新快照,最后用一次原子引用切换。

我会把当前配置放在 AtomicReference<ConfigSnapshot>volatile 引用里。更新线程拉取新版本后,在私有对象中完成解析、默认值补齐、跨字段校验和依赖预热;全部成功后再一次 set。业务线程每次请求只读取一次引用,所以要么看到旧版本,要么看到完整新版本。

ConfigSnapshot next = loadAndValidate(version);
current.set(next);

快照必须深度不可变。外层 unmodifiableMap 但 value 还能修改,依然会让读线程看到半状态。发布后我会保留版本号、校验摘要和上一版本,指标异常时能立即切回。

如果配置切换还要建立连接或加载大文件,这些慢操作都在交换引用之前完成;旧资源不能立即关闭,要等正在使用旧快照的请求结束,或者做引用计数和延迟回收。

思路拆解问题分析

这里要保证的是 整份配置的一致可见性,不是每个 Map 操作线程安全。把 HashMap 换成 ConcurrentHashMap 只能保证单次 put 安全,业务线程仍可能读到“新开关 + 旧阈值”的混合版本。