exchanger 是 java 并发包中用于两个线程同步交换数据的工具类,要求双方在交换点配对阻塞、原子交换对象,仅支持严格双线程协作,可重复使用且线程安全。

Exchanger 是 Java 并发包(java.util.concurrent)中一个专门用于两个线程之间同步交换数据的工具类。它不是简单的共享变量或阻塞队列,而是要求两个线程在同一个“交换点”相遇并互换数据——就像两人面对面交递信封,必须同时到场、同时交接。
核心机制:配对阻塞交换
Exchanger 的关键行为是:调用 exchange(V x) 方法的两个线程会相互等待,直到双方都到达交换点,然后原子性地交换各自传入的对象。如果只有一个线程调用,它将一直阻塞;若超时未等到配对线程,可选择抛出 TimeoutException(使用带超时的重载方法)。
- 只能用于严格两方协作,不支持多线程广播或轮询式交换
- 每次成功交换后,Exchanger 可重复使用(内部自动重置配对状态)
- 交换过程线程安全,无需额外同步
基础用法:双线程数据配对
典型场景如生产者-消费者配对、乒乓缓冲区切换、请求-响应协同等。下面是一个模拟“数据采集线程”与“数据处理线程”交换缓冲区的示例:
Exchanger<int> exchanger = new Exchanger();
Thread producer = new Thread(() -> {
int[] buffer = new int[1024];
for (int i = 0; i {
int[] buffer = new int[1024];
for (int i = 0; i
<h3>注意事项与常见陷阱</h3>
<p>Exchanger 行为看似简单,但易因线程生命周期或异常导致死锁或丢失配对:</p>
<ul>
<li>
<strong>线程需成对启动且存活时间匹配</strong>:若一方提前结束,另一方在 <code>exchange()</code> 中永久阻塞(除非设超时)</li>
<li>
<strong>避免在 exchange() 中执行耗时操作</strong>:交换本身应轻量,否则会拖慢配对效率,甚至引发级联延迟</li>
<li>
<strong>注意 null 值语义</strong>:可以交换 <code>null</code>,但需双方约定好含义(例如表示“终止信号”)</li>
<li>
<strong>超时控制推荐用于健壮性保障</strong>:<code>exchange(V x, long timeout, TimeUnit unit)</code> 可防止单点故障导致整个流程卡死</li>
</ul>
<h3>适用场景与替代方案对比</h3>
<p>Exchanger 最适合<strong>固定双角色、周期性、等量数据协同</strong>的场景,比如:</p>
<ul>
<li>双缓冲图形渲染(前台/后台帧缓冲区交换)</li>
<li>网络协议中请求线程与响应解析线程的数据接力</li>
<li>测试中模拟双向 RPC 调用配对</li>
</ul>
<p>若需一对多、带优先级、或异步非阻塞交换,应考虑 <code>SynchronousQueue</code>、<code>BlockingQueue</code> 或 <code>Phaser</code> 等更灵活的工具。Exchanger 的优势在于语义明确、开销极小、无中间存储——真正实现“一手交钱、一手交货”的强配对语义。</p></int>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











