发布于2026-08-05 阅读(0)
扫一扫,手机访问
在 Java 的 java.util.concurrent 包里,有一个不太起眼但很好用的工具——Exchanger。它专门用来在两个线程之间交换数据,用起来非常直观。
一个带有两个“格子”的容器。通过调用 exchange() 方法,每个线程可以把数据放进其中一个格子。当两个格子都被填满时,Exchanger 会自动把两个格子里的数据交换一下,再分别返回给对应的线程。这样一来,两个线程就完成了信息交换,整个过程是同步且安全的。
下面是一个最简单的示例代码,帮你快速上手:
package test;
import java.util.concurrent.Exchanger;
class ExchangerTest extends Thread {
private Exchanger exchanger;
private String string;
private String threadName;
public ExchangerTest(Exchanger exchanger, String string,
String threadName) {
this.exchanger = exchanger;
this.string = string;
this.threadName = threadName;
}
public void run() {
try {
System.out.println(threadName + ": " + exchanger.exchange(string));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
Exchanger exchanger = new Exchanger<>();
ExchangerTest test1 = new ExchangerTest(exchanger, "string1",
"thread-1");
ExchangerTest test2 = new ExchangerTest(exchanger, "string2",
"thread-2");
test1.start();
test2.start();
}
}
每个线程在执行过程中都调用同一个 Exchanger 对象的 exchange 方法,传递自己的数据。当两个线程都把数据放入“格子”后,Exchanger 会交换数据并返回。运行结果如下图所示:

需要特别注意的是,Exchanger 只适用于两个线程的数据交换。如果超过两个线程同时调用同一个 Exchanger 对象,结果就会变得随机。因为 Exchanger 根本不在乎线程数量,它只关心两个“格子”是否被填满。一旦两个格子都满了,它就认为配对成功,立即执行交换——至于跟谁配、剩余线程怎么办,它一概不管。
不妨把上面的示例改一改,在第 33 行之后再加一个线程 test3,线程名设为 thread-3,交换字符串改为 string3:
ExchangerTest test3 = new ExchangerTest(exchanger, "string3","thread-3"); test3.start();
此时再运行,结果就不确定了。多次测试会发现,test1 可能和 test3 配对,也可能和 test2 配对。而那个落单的线程,因为没有配对成功,会一直阻塞在 exchange 方法上,永远等待下去——除非你强制终止它。

Exchanger 的核心设计就是“一对二”的交换,使用场景很明确:两个线程需要同步交换数据时,它是最简洁的方案。一旦超出两个线程,行为就会变得不可控,未配对的线程会永久阻塞,所以记得按需控制线程数量。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8