exchanger是java并发包中专为两个线程成对交换数据设计的轻量级同步工具,要求双方同时到达exchange()点才能原子性互换对象引用,无缓冲、无复制、不支持多线程,适用于双缓冲、流水线双阶段等严格对等协作场景。

Exchanger 是 Java 并发包(java.util.concurrent)中一个轻量级的同步工具,专为**两个线程之间成对交换数据**而设计。它在多任务流水线场景中非常适用——比如“生产者-消费者”式双阶段处理、前后端缓冲区轮换、图像处理中的帧缓冲切换等,只要满足“两两配对、交替协作”的结构,Exchanger 就比阻塞队列或显式锁更简洁高效。
适合流水线的典型结构
Exchanger 要求参与交换的线程数量严格为偶数,且必须两两配对等待。因此它天然适配双阶段流水线:
- 阶段 A 线程(如采集/解析)完成一批数据后,调用
exchange(data)阻塞等待; - 阶段 B 线程(如转换/渲染)同时调用
exchange(null)或上一轮结果,双方即刻交换并继续执行; - 无需额外队列或状态管理,避免了缓冲区堆积和空转等待。
避免线程错配与超时风险
若一方提前退出或异常中断,另一方会无限期阻塞。实际使用中应:
- 始终配合
try-catch捕获InterruptedException; - 优先使用带超时的
exchange(V x, long timeout, TimeUnit unit),例如设置 5 秒超时; - 确保配对线程生命周期可控——建议用固定大小的线程池(
Executors.newFixedThreadPool(2)),而非无限制创建。
共享缓冲区轮换的实用写法
常见于内存敏感型流水线(如实时音视频处理),用 Exchanger 实现双缓冲零拷贝切换:
- 定义两个
byte[]缓冲区:bufferA和bufferB; - A 线程填满
bufferA后,调用exchanger.exchange(bufferA); - B 线程拿到
bufferA处理,同时将已处理完的bufferB交还; - 下一轮 A 线程直接复用
bufferB,实现缓冲区循环利用。
不适用于多对多或动态参与者场景
Exchanger 不是通用协调器:
- 三个线程调用 exchange 可能导致其中两个先配对,第三个永远阻塞;
- 无法像
Phaser或CyclicBarrier支持动态注册/注销; - 若流水线需扩展为三阶段(A→B→C),应改用
TransferQueue或分段 Exchanger 组合,而非强行复用单个实例。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











