exchanger 是 java 并发包中专用于两个线程间交换数据的协作工具,通过 exchange() 实现等待配对与原子交换,适用于双缓冲场景,如生产者-消费者模型中的缓冲区交接。

Exchanger 是 Java 并发包(java.util.concurrent)中一个轻量级的线程间协作工具,专用于**两个线程之间交换数据**。它特别适合实现“双缓冲”场景——比如一个线程持续填充缓冲区,另一个线程同时消费/处理前一轮的数据,两者通过 Exchanger 同步交接,避免锁竞争和内存可见性问题。
核心机制:一次配对,一次交换
Exchanger 的本质是“等待配对 + 原子交换”。调用 exchange(V x) 的线程会阻塞,直到另一个线程也调用 exchange,然后两者原子性地交换各自传入的对象引用。注意:
- 只支持**恰好两个线程**参与;
- 每次交换后,双方拿到的是对方上次传入的对象;
- 第一次调用时若无配对线程,会一直等待(可设超时避免死等)。
典型双缓冲同步模式
以“生产者-消费者”双线程模型为例(如图像帧处理、日志批量刷盘):
- 准备两个缓冲区(如
byte[] bufferA,byte[] bufferB),初始由生产者持有空缓冲区,消费者持有空缓冲区; - 生产者填满当前缓冲区后,调用
exchanger.exchange(buffer),挂起等待; - 消费者在另一线程中也调用
exchanger.exchange(buffer),双方交换缓冲区引用; - 生产者拿到消费者刚处理完的缓冲区(可立即复用),消费者拿到刚填满的新数据。
代码示例:安全的双缓冲日志收集
以下是一个简化但完整的双缓冲日志场景:
Exchanger<list>> exchanger = new Exchanger();
List<string> buffer1 = new ArrayList();
List<string> buffer2 = new ArrayList();
<p>// 生产者线程
new Thread(() -> {
List<string> current = buffer1;
while (!Thread.currentThread().isInterrupted()) {
// 填充当前缓冲区(模拟采集日志)
current.add("log-" + System.currentTimeMillis());
if (current.size() >= 100) {
try {
// 交换:把填满的交给消费者,换回已清空的
current = exchanger.exchange(current);
current.clear(); // 复用前清空
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}).start();</string></p>
<p>// 消费者线程
new Thread(() -> {
List<string> current = buffer2;
while (!Thread.currentThread().isInterrupted()) {
try {
// 等待生产者交来新数据
current = exchanger.exchange(current);
// 处理这批日志(如写入文件)
processLogs(current);
current.clear(); // 清空后还给生产者
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
</string></p></string></string></list>关键点:
- 缓冲区对象本身不共享,只交换引用,避免同步开销;
- 每次交换后双方都主动 clear(),确保复用安全;
- 不依赖外部锁或 volatile,Exchanger 内部保证内存可见性和原子性。
注意事项与替代建议
使用 Exchanger 需警惕:
- 若一个线程异常退出,另一个线程在
exchange()处永久阻塞(可用带超时的exchange(V x, long timeout, TimeUnit unit)防御); - 不适合多于两个线程的场景(此时应考虑
CyclicBarrier或Phaser); - 缓冲区对象需线程安全复用(如
ArrayList本身非线程安全,但因每次仅被单一线程独占使用,无需额外同步)。
不复杂但容易忽略:交换前确保缓冲区状态已就绪(如填满或清空完成),否则可能造成数据丢失或重复处理。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











