exchanger不是负载均衡器,而是专为两个线程设计的双向交换工具,通过汇合即交换机制原子性互换对象引用,仅支持严格配对,第三线程会无限等待;交换的是引用而非深拷贝,需配合超时保护,典型应用为双缓冲流水线。

Exchanger 本身不是负载均衡器,也不直接分配任务或调度线程,但它能在特定协作型负载场景中,成为实现“对等任务动态再平衡”的关键桥梁——尤其适用于两个工作线程持续配对、交替承担不同阶段计算的轻量级均衡模式。
适用前提:成对、对称、阶段化任务
Exchanger 要发挥负载调节作用,必须满足三个条件:
- 任务天然可拆分为两个逻辑阶段(如“预处理 ↔ 后处理”、“采集 ↔ 转换”),且两阶段耗时存在波动性
- 有两个长期运行的工作线程,各自专注一个阶段,但不固定绑定某类数据
- 通过交换缓冲区或中间结果,让快线程不空等、慢线程不积压,形成隐式速率匹配
典型实践:双阶段流水线中的反压调节
例如一个实时日志解析系统:
- 线程 A 负责从 Kafka 拉取原始日志并做轻量清洗(解码、过滤),写入本地 List
- 线程 B 负责对这批日志做聚合统计、规则匹配等重计算
- 两者用
Exchanger<list>></list>交换批次数据
当 A 处理快、B 处理慢时,A 在 exchange() 处阻塞,自动暂停拉取,避免内存堆积;当 B 加速后,A 立即获得空缓冲区继续工作。这种天然的“背压传导”无需额外信号量或队列容量控制,就实现了两阶段间动态节奏同步。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
配合超时提升鲁棒性
生产环境中,不能依赖无限等待。应使用带超时的 exchange(V, timeout, unit):
- 设 500ms 超时:若 B 异常卡死,A 不会永久挂起,可主动丢弃/降级/告警该批次
- 超时后 A 可复用当前缓冲区重试,或切换至备用处理路径(如写入本地磁盘暂存)
- 需捕获
TimeoutException并记录指标(如“交换延迟次数”),用于后续扩容或调优
与真正负载均衡器的区别
需明确:Exchanger 不替代 ForkJoinPool、WorkStealingPool 或自定义 TaskRouter。
- 它不支持 ≥3 线程参与,无法做多节点分发
- 它不感知任务优先级、资源占用率或 CPU 使用率
- 它的“均衡”是被动节流,而非主动调度——本质是协作同步,不是任务分派
真正需要横向扩展或异构任务分发时,应结合 ExecutorService + BlockingQueue + 自定义策略;Exchanger 的价值,在于把两个紧密耦合、强依赖的子任务,用最轻量的方式拧成一个呼吸同频的整体。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










