为何Moshi类中adapterCache未采用ConcurrentHashMap而使用synchronized块?
Moshi选择用synchronized块来保护Adapter缓存而非ConcurrentHashMap,核心原因集中在兼容性、逻辑可控性、可维护性以及实际场景的性能权衡上:
历史兼容性与行为一致性:Moshi最初基于Java开发,早期版本需要适配广泛的JVM环境。
synchronized的并发控制逻辑在所有JVM版本中表现一致,无需考虑不同JDK版本中ConcurrentHashMap的API变更或并发行为差异,避免了兼容性隐患。严格的创建原子性保障:Adapter的创建涉及类型解析、注解处理、自定义策略匹配等复杂逻辑,
synchronized块能确保同一时间只有一个线程为特定类生成Adapter,彻底杜绝重复创建的可能。尽管ConcurrentHashMap.computeIfAbsent也提供原子性,但如果Adapter创建流程存在副作用(比如依赖全局状态、触发关联初始化),synchronized的独占执行模式更易把控和预测。逻辑简洁性与可维护性:Moshi的缓存流程并非简单的键值存取,还包含自定义Adapter查找、类型适配校验等前置步骤。用
synchronized包裹完整的查询+创建逻辑,代码边界清晰,维护者能直观理解并发控制的范围;而ConcurrentHashMap的并发特性会让这部分逻辑拆分得更零散,增加理解和维护的成本。实际场景的性能权衡:在绝大多数应用场景中,获取Adapter的并发请求量并不高,
synchronized带来的性能开销完全可接受。ConcurrentHashMap虽有更优的并发性能,但会引入额外内存开销和复杂度,对于Moshi的典型使用场景来说属于过度优化。
内容的提问来源于stack exchange,提问作者Petromir Dzhunev

