游乐游手机版
首页/编程语言/文章详情

Java Exchanger线程间数据交换用法与示例教程

时间:2026-08-06 17:44
JavaExchanger是并发工具类,用于两个线程间同步交换数据,通过exchange()方法将数据放入容器并自动交换。该工具仅支持两个线程配对,超出数量会导致配对随机,且未配对线程永久阻塞。内部通过CAS机制实现线程安全,适用于生产者-消费者等经典场景。

在 Java 的 ja va.util.concurrent 包里,有一个不太起眼但非常实用的工具——Exchanger。它专门用于在两个线程之间交换数据,使用起来直观且高效。

可简单地将 Exchanger 对象理解为双格数据交换容器

它本质上是一个带有两个“格子”的容器。当线程调用 exchange() 方法时,会将数据放入其中一个格子。当两个格子都被填满后,Exchanger 会自动交换两个格子中的数据,并分别返回给对应的线程。这样,两个线程便完成了数据同步交换,整个过程是线程安全且同步的。

下面提供一段最简示例代码,帮助你快速上手 Exchanger 的使用:

package test;
import ja va.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 会自动交换数据并返回给各自线程。运行结果如下图所示:

Ja vaExchanger在两个线程间交换数据示例

需要特别注意的是,Exchanger 仅适用于两个线程之间的数据交换。如果有超过两个线程同时调用同一个 Exchanger 对象,交换结果将变得不可预测。这是因为 Exchanger 并不关心线程数量,它只关注两个“格子”是否被填满。一旦两个格子都满了,它就认为配对成功并立即执行交换——至于与哪个线程配对、剩余的线程如何处理,它一概不予理会。

不妨修改上面的示例,在第 33 行之后增加一个线程 test3,将其线程名设为 thread-3,交换字符串设为 string3

ExchangerTest test3 = new ExchangerTest(exchanger, "string3","thread-3");
test3.start();

此时再运行程序,结果将变得不确定。多次测试可以发现,test1 可能和 test3 配对,也可能和 test2 配对。而那个未能配对的线程,由于没有成功配对,会一直阻塞在 exchange 方法上,陷入永久等待——除非你手动强制终止它。

Ja vaExchanger多线程配对示例

总结与核心要点

Exchanger 的核心设计就是“一对二”的数据交换机制,其使用场景非常明确:当两个线程需要同步交换数据时,它是最简洁高效的解决方案。一旦线程数量超过两个,行为将变得不可控,未配对的线程会永久阻塞,因此在实际使用中务必按需控制线程数量。

来源:https://www.jb51.net/program/36859416m.htm
上一篇RabbitMQ消息积压排查:从指标定位到消费者扩容 下一篇服务器间文件目录快速转移的Shell命令实现
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Yum怎么查找已安装软件包及安装信息
编程语言 · 2026-08-17

Yum怎么查找已安装软件包及安装信息

使用yumlistinstalled列出所有已安装软件包,配合grep可快速过滤特定软件;yuminfo查看元数据和安装状态;yumsearch通过关键词搜索包名。以上命令均需sudo权限执行。

Debian系统中Python与Java互操作方法详解
编程语言 · 2026-08-17

Debian系统中Python与Java互操作方法详解

在Debian系统中,Python与Java互操作有五种方案:Jython直接调用Java类库但仅支持Python2;GraalVM实现多语言高性能协作;JNI底层灵活但复杂度高;Web服务通过RESTfulAPI解耦;消息队列支持异步解耦。各方案适用场景不同,需根据需求选择。

@FunctionalInterface校验逻辑与函数式接口强制约束规范
编程语言 · 2026-08-17

@FunctionalInterface校验逻辑与函数式接口强制约束规范

@FunctionalInterface 这个注解在 Java 开发中很常见,很多人都用过,但真正彻底理解它作用的人,其实并不算多。归根结底,它本质上是一种编译期契约声明,同时也是编译器进行强制校验的一道安全锁。它不会在运行时改变接口行为,也不会给接口增加任何额外能力。但不要因此低估它——在提升代码

Ubuntu上如何测试JavaScript性能与运行效率
编程语言 · 2026-08-17

Ubuntu上如何测试JavaScript性能与运行效率

Ubuntu上JavaScript性能测试实用指南 一 测试类型与指标 在Ubuntu环境中进行JavaScript性能测试,首先要明确测试目标。从实际项目经验来看,JS性能测试通常可以分为三大类,不同类型关注的性能指标也不一样: 前端页面与渲染性能:核心指标包括FPS(帧率)、长任务、布局与重绘,

LNMP环境容量规划怎么做更合理
编程语言 · 2026-08-17

LNMP环境容量规划怎么做更合理

LNMP环境容量规划需评估CPU、内存、磁盘I O等现状,明确响应时间等关键指标,基于历史流量预测负载,倒推服务器资源,设计水平或垂直扩展方案,通过压测验证,并持续监控调整,定期备份恢复,记录决策并同步团队。