exchanger 是 java 并发包中用于成对线程同步交换数据的工具,要求恰好两个线程在汇合点阻塞等待并原子性交换对象,支持超时与中断处理,典型应用于双缓冲场景。

Exchanger 是 Java 并发包(java.util.concurrent)中一个轻量级的线程间协作工具,专用于**成对线程之间同步交换数据**。它不适用于多线程广播或任意线程通信,而是严格设计为两个线程在某个汇合点(exchange point)彼此等待、交换对象后继续执行。
核心机制:成对阻塞交换
调用 exchanger.exchange(data) 的线程会阻塞,直到另一个线程也调用同一 Exchanger 实例的 exchange() 方法。一旦双方都到达,它们原子性地交换各自传入的对象,并各自获得对方的数据后返回。
关键特性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 必须恰好两个线程参与一次交换;第三个线程调用会一直阻塞,直到有配对线程出现(或超时)
- 交换是同步且原子的——不会出现数据撕裂或中间状态
- 支持带超时的
exchange(V x, long timeout, TimeUnit unit),避免无限等待 - 若一方中断,另一方会抛出
InterruptedException
典型使用场景示例:双缓冲数据处理
比如一个生产者线程不断填充缓冲区 A,一个消费者线程处理缓冲区 B;处理完后双方交换缓冲区引用,实现零拷贝切换:
Exchanger<int> exchanger = new Exchanger();
int[] buffer1 = new int[1024];
int[] buffer2 = new int[1024];
// 生产者线程
new Thread(() -> {
for (int i = 0; i {
for (int i = 0; i
</int>
注意事项与常见陷阱
- 必须共用同一个 Exchanger 实例:不同实例之间无法配对,会导致永久阻塞
- 类型必须一致:泛型确保交换对象类型安全,避免运行时类型错误
- 不要在 exchange() 中执行耗时操作:否则会拖慢配对线程,影响整体吞吐
-
异常需妥善处理:如
InterruptedException或TimeoutException,避免线程静默退出 - 不支持“单向”或“多次交换同一方”:每次调用都代表一次新配对意愿,旧等待会被覆盖(实际是取消前次等待并重新注册)
替代方案对比
如果需要多线程协作或更灵活的交换逻辑,可考虑:
-
SynchronousQueue:适合“传递式”交接(一个放、一个取),但不是双向交换 -
Phaser或CyclicBarrier:用于多线程同步到达,不交换数据 -
BlockingQueue+ 双端操作:可模拟但代码更重、无原子交换语义
Exchanger 的价值在于语义简洁、开销低、逻辑清晰——当你明确只需要两个线程互换一份数据时,它就是最直接的选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










