exchanger是java并发包中专为两个线程成对协作设计的轻量级同步工具,核心机制是“同时到达、即时交换”,通过内部插槽与cas实现无锁配对,仅支持严格双向阻塞交换,不适用于多线程场景。

Exchanger 不是通用的同步器,它专为两个线程间成对协作而设计,核心在于“同时到达、即时交换”。它不依赖锁或共享变量,而是通过内部插槽(slot)与CAS操作实现轻量级配对,本质是一个双向阻塞点。
Exchanger 的配对交换逻辑
两个线程必须各自调用 exchange(V x) 才能完成一次数据互换。任意一方先到,就进入等待状态;后到者触发交换并唤醒前者——双方几乎原子性地拿到对方的数据。
- 若仅一个线程调用 exchange,它会一直阻塞,直到另一个线程也抵达
- 交换完成后,两个线程各自持有对方传入的对象,原对象即被替换
- 同一个 Exchanger 实例不能支持三线程及以上直接配对,多线程需自行调度成对使用
带超时的 exchange 防止死等
生产环境必须考虑异常场景:比如某线程因异常、延迟或退出未能到达交换点。这时应使用重载方法 exchange(V x, long timeout, TimeUnit unit)。
- 超时后抛出
TimeoutException,当前线程可捕获并执行降级逻辑(如重试、记录日志、返回默认值) - 注意:超时只作用于当前调用线程,不影响另一方行为;对方若后续到达,仍会完成交换,但已无等待者接收结果
- 建议设置合理超时值,例如 I/O 类任务设为 3–5 秒,计算类任务可更短
典型适用场景与避坑提示
Exchanger 最适合需要严格双向确认、且天然成对的协作模型,不是万能队列替代品。
- 双缓冲处理:线程 A 填充缓冲区1,线程 B 消费缓冲区2;二者在交换点互换缓冲区引用,避免拷贝与锁竞争
- 实时交易确认:如玩家A发起交易,玩家B必须同步确认,双方数据(物品清单、金币数)在 exchange 点一次性交换并校验
- 避免误用:不要用它替代 BlockingQueue 或 Phaser;多个线程共用同一 Exchanger 会导致高争用,性能急剧下降
底层轻量协作的关键细节
Exchanger 内部采用“消除 arena”机制,而非单一共享 slot,以缓解多线程竞争。这意味着:即使多个线程并发调用,系统也会尝试让它们分散到不同插槽,最终仍保证任意两线程可配对成功。
- 这种设计使它在低并发(2–4线程)下极高效,但在高并发密集使用同一实例时,吞吐会明显下降
- 无需手动清理或重置,每次 exchange 调用都是独立事件,状态自动管理
- 线程中断会抛出 InterruptedException,调用方应正确响应并恢复中断状态











