Exchanger是Java并发包中专为两个线程在同步点双向原子交换数据设计的轻量级工具,通过配对等待机制实现无锁、无共享变量、无中间拷贝的安全交换,仅支持严格成对协作,不适用于多线程场景。

Exchanger 是 Java 并发包中专为「两个线程在同步点双向交换数据」而设计的轻量级工具。它不依赖锁或共享变量,而是通过内部配对机制,让双方线程在调用 exchange() 时自然汇合、原子交换,整个过程无中间拷贝、无额外同步开销。
同步点如何触发双向交换
两个线程调用同一个 Exchanger 实例的 exchange(V x) 方法时,并非谁先到谁主导,而是彼此等待形成“配对”。只要双方都抵达该点,JVM 就立即完成数据互换并唤醒两者——这是一次原子性的双线程协作事件。
- 线程 A 调用
ex.exchange("A-data")→ 进入等待状态 - 线程 B 调用
ex.exchange("B-data")→ 触发配对,双方同时解除阻塞 - A 收到
"B-data",B 收到"A-data",各自继续执行
数据流转的关键约束与保障
Exchanger 的高效性建立在严格的前提上:它只服务成对线程,且每次交换仅绑定最近一次未完成的调用。这意味着:
- 同一 Exchanger 实例可被多个线程使用,但只有两个调用能组成一对;第三个调用会等待下一个“空闲”线程,不保证与前一个伙伴重连
- 交换是引用传递,不复制对象本身,适合大对象(如缓冲区数组)的快速交接
- 内部基于 CAS 和自旋优化,避免传统锁带来的上下文切换开销
防止卡死:超时控制与异常处理
生产环境必须防范单边调用导致的永久阻塞。推荐始终使用带超时的重载方法:
-
ex.exchange(data, 2, TimeUnit.SECONDS)—— 等待最多 2 秒,超时抛TimeoutException - 捕获
InterruptedException后应恢复中断状态:Thread.currentThread().interrupt() - 避免传
null值,除非业务逻辑明确支持并做了判空处理
典型适用场景与误用提醒
它不是通用通信通道,而是为特定协作模式定制的“双轨交汇站”:
- ✅ 双缓冲切换:线程 A 填满 buffer1,线程 B 处理 buffer2;交换引用后,A 处理 buffer2,B 填 buffer1
- ✅ 流水线配对:加密线程与解密线程轮流交换数据块
- ❌ 不适用于多于两个线程的广播、聚合或轮询场景
- ❌ 不适合异步通知或单向推送(此时应选
BlockingQueue或TransferQueue)

















