【JUC】交换器Exchanger详解

简介: 【JUC】交换器Exchanger详解

前言


JDK中提供了不少的同步工具,现在分享一个相对比较冷门的同步工具——交换器(Exchanger)。你知道Exchanger的作用是什么吗?实现机制是什么?可以用来做什么呢?


Exchanger介绍


交换器(Exchanger),顾名思义,用于两个线程之间进行数据交换的。

简单来说,就是一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据。如下图所示:


1671202277083.jpg


两个线程通过 exchange() 方法交换数据,如果第一个线程先执行 exchange() 方法,它会一直等待第二个线程也执行 exchange 方法,当两个线程都到达同步点时,这两个线程就可以交换数据


API介绍


构造方法

  • Exchanger():创建一个交换器

常用方法

  • V exchange(V x): 交换数据,如果只有一个线程,会阻塞,直到另外一个线程也调用exchange, 支持中断
  • V exchange(V x, long timeout, TimeUnit unit): 带超时参数的交换数据


Exchanger使用


这不,马上圣诞节要到了,你要和你对象交换礼物,不准备的话,你就要死的很惨~~我们就可以用Exchanger来实现。

@Slf4j(topic = "c.ExchangerTest")
public class ExchangerTest {
    public static void main(String[] args) throws InterruptedException {
        Exchanger<String> exchanger = new Exchanger<>();
        Thread boy = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("你开始准备礼物~~~~~~~~~~~~");
                try {
                    // 模拟准备礼物时间
                    Thread.sleep(5000);
                    String gift = "IPhone 14";
                    log.info("你送了礼物: {}",  gift);
                    String recGift = exchanger.exchange(gift);
                    log.info("你收到了礼物: {}",  recGift);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread girl = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("女朋友开始准备礼物~~~~~~~~~~~~");
                try {
                    // 模拟准备礼物时间
                    Thread.sleep(6000);
                    String gift = "一个吻";
                    log.info("女朋友送了礼物: {}",  gift);
                    String recGift = exchanger.exchange(gift);
                    log.info("女朋友收到了礼物: {}",  recGift);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        boy.start();
        girl.start();
        boy.join();
        girl.join();
    }
}

运行结果:


1671202299601.jpg


  • 中间阻塞等待了一秒,直到你女朋友也准备好了礼物。


实现机制


实现机制也很容易能够想到,Exchanger类中定义一个槽位slot,

  1. A线程交换数据时,发现slot为空,则将需要交换的数据放在slot中, 阻塞当前线程,等待其它线程进来交换数据
  2. 等线程B进来,读取A设置的数据,然后设置线程B需要交换的数据,然后唤醒A线程。

Exchanger的源码实现大家感兴趣的话,自己可以看看。


总结


本文讲解了交换器Exchanger,是jdk5中引入的一个同步器。实际上在平时工作场景中基本上很少应用,按照官方注释说可以应用在基因算法或者管道设计,太抽象了,大家就当扩扩知识面吧。

目录
相关文章
|
存储 运维 数据处理
AIGC浪潮对数据中心基础设施发展的影响
【1月更文挑战第19天】AIGC浪潮对数据中心基础设施发展的影响
435 1
AIGC浪潮对数据中心基础设施发展的影响
|
分布式计算 大数据 Hadoop
【大数据开发技术】实验03-Hadoop读取文件
【大数据开发技术】实验03-Hadoop读取文件
426 0
|
SQL 运维 Oracle
Oracle 超时设置2:设置实例级参数
Oracle超时设置系列的第二篇文章,设置实例级参数
876 0
|
关系型数据库 MySQL BI
关系型数据库选择合适的数据库管理系统
【5月更文挑战第4天】关系型数据库选择合适的数据库管理系统
673 4
关系型数据库选择合适的数据库管理系统
|
数据采集 运维 监控
ERP系统中的生产过程监控与质量管理
【7月更文挑战第25天】 ERP系统中的生产过程监控与质量管理
524 0
|
机器学习/深度学习 开发者 数据格式
Gradio如何使用
**Gradio** 是一个开源 Python 库,用于快速创建和部署机器学习模型的用户界面。它支持多种输入输出形式,如文本、图像、音频等,无需复杂 Web 开发知识即可实现模型的直观展示和交互。Gradio 特点包括简单易用、实时更新、多样的输入输出形式以及轻松部署。通过几个简单的步骤,即可创建和分享功能强大的机器学习应用。
557 0
|
机器学习/深度学习 人工智能 自然语言处理
AIGC-基于EAS服务快速部署一个AI视频生成
AIGC-基于EAS服务快速部署一个AI视频生成
|
Java 大数据 Android开发
探索Java编程语言的优势和应用领域
Java是一种广泛应用于软件开发领域的高级编程语言。它凭借其强大的功能和丰富的生态系统,在众多应用领域中得到了广泛应用。本文将为您介绍Java的优势以及它在各个领域中的应用。
1247 2
|
Dubbo 前端开发 Java
maven多模块和依赖冲突问题汇总记录(上)
maven多模块和依赖冲突问题汇总记录(上)
729 0
GitHub——如何生成Personal access tokens
GitHub——如何生成Personal access tokens
166 0