JUC之花里胡哨Exchanger

本文深入解析Java并发包中Exchanger类的功能与使用,通过生动的电竞场景示例,展示如何利用Exchanger实现线程间数据交换,探讨其在实际应用中的作用与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

JUC中的Exchanger允许成对的线程在指定的同步点上通过exchange方法来交换数据。如果第一个线程先执行exchange方法,它会一直等待第二个线程也 执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将当前线程生产 出来的数据传递给对方。

示例

一般来说,辅助要跟着打野发育,抓人.但两个人不沟通的话,就只能靠爱情的默契.因此做为一名合格的打野/辅助,一定会分分钟钟发送消息,让对方了解,让对方感动💖.就像谈恋爱一样,甜死她💘!
下面模拟两个选手通过Exchanger交换数据的简单示例

public class ExchangerTest {
    public static void main(String[] args) {
        final Exchanger<String> exchanger = new Exchanger<>();

        new Thread(() -> {
            System.out.println("打野:全军出击");
            try {
                String exchange = exchanger.exchange("嘤嘤怪,先过去反蓝");
                System.out.println("嘤嘤怪辅助:" + exchange);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("得到:蓝加成");
        }, "thread1").start();

        new Thread(() -> {
            System.out.println("辅助:全军出击");
            try {
                TimeUnit.SECONDS.sleep(5);
                String exchange = exchanger.exchange("收到");
                System.out.println("猛男打野:" + exchange);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread2").start();
    }
}

在定义Exchanger的时候需要指定交换的数据类型,这里为String类型。exchange方法用于向另一个线程发送数据,方法的返回值为另一个线程发送过来的数据。
只有当成对👩‍❤‍👨的线程都到达同步点的时候,才会执行数据交换操作.因此先让嘤嘤怪休眠5秒,后进行反野
上面例子输出如下:

打野:全军出击
辅助:全军出击
猛男打野:嘤嘤怪,先过去反蓝
嘤嘤怪辅助:收到
得到:蓝加成

设置超时时间

有时由于网络问题造成延迟,没有及时收到消息,因此为了打野的发育,放弃辅助一个人去反野

public class ExchangerTest {
    public static void main(String[] args) {
        final Exchanger<String> exchanger = new Exchanger<>();

        new Thread(() -> {
            System.out.println("打野:全军出击");
            try {
                String exchange = null;
                try {
                    exchange = exchanger.exchange("嘤嘤怪,先过去反蓝",3, TimeUnit.SECONDS);
                    System.out.println("嘤嘤怪辅助:" + exchange);
                    System.out.println("得到:蓝加成");
                } catch (TimeoutException e) {
                    System.out.println("打野被拿了一血");
                    e.printStackTrace();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread1").start();

        new Thread(() -> {
            System.out.println("辅助:全军出击");
            try {
                TimeUnit.SECONDS.sleep(5);
                String exchange = exchanger.exchange("收到");
                System.out.println("猛男打野:" + exchange);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread2").start();
    }
}

因为辅助要等到5秒才回复,打野只能等3秒,而打野在等待3秒后只身去反野,结果抛出TimeoutException异常了。5秒后由于没有线程再和辅助交换数据,所以辅助会一直等待:

打野:全军出击
辅助:全军出击
打野被拿了一血
java.util.concurrent.TimeoutException
	at java.util.concurrent.Exchanger.exchange(Exchanger.java:626)
	at com.kaleldo.kaleldo.threadTest.ExchangerTest.lambda$main$0(ExchangerTest.java:16)
	at java.lang.Thread.run(Thread.java:748)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值