欢迎关注专栏【JAVA并发】

前言

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

Exchanger介绍

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

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

两个线程通过 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(); }
}

运行结果:

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

实现机制

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

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

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

总结

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

如果本文对你有帮助的话,请留下一个赞吧

【JUC】交换器Exchanger详解的更多相关文章

  1. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  2. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  3. java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService

    这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...

  4. JUC中的AQS底层详细超详解

    摘要:当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒? 本文分享自华为云社区<JUC中的AQS底层详细超详解,剖 ...

  5. 多线程之 Final变量 详解

    原文: http://www.tuicool.com/articles/2Yjmqy 并发编程网:http://ifeve.com/java-memory-model/ 总结: Final 变量在并发 ...

  6. Dubbo架构设计详解-转

    Dubbo架构设计详解  2013-09-03 21:26:59    Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  7. java并发包java.util.concurrent详解

    线程池ThreadPoolExecutor的使用 并发容器之CopyOnWriteArrayList 并发容器之CopyOnWriteArraySet 数据结构之ConcurrentHashMap,区 ...

  8. (转)Java并发包基石-AQS详解

    背景:之前在研究多线程的时候,模模糊糊知道AQS这个东西,但是对于其内部是如何实现,以及具体应用不是很理解,还自认为多线程已经学习的很到位了,贻笑大方. Java并发包基石-AQS详解Java并发包( ...

  9. .Net使用RabbitMQ详解 转载http://www.cnblogs.com/knowledgesea/p/5296008.html

    .Net使用RabbitMQ详解   序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其 ...

  10. HAProxy详解(一):HAProxy介绍【转】

    一.高性能负载均衡软件HAProxy介绍: 随着互联网业务的迅猛发展,大型电商平台和门户网站对系统的可用性和可靠性要求越来越高,高可用集群.负载均衡集群成为一种热门的系统架构解决方案.在众多的负载均衡 ...

随机推荐

  1. 静态文件:Static Files

    官方文档地址:https://fastapi.tiangolo.com/zh/tutorial/static-files/ from fastapi import FastAPI from fasta ...

  2. 第五章:Admin管理后台 - 3:Admin文档生成器

    Django的admindocs应用可以从模型.视图.模板标签等地方获得文档内容. 一.概览 要激活admindocs,请按下面的步骤操作: 在INSTALLED_APPS内添加django.cont ...

  3. 18. Fluentd输出插件:out_stdout用法详解

    stdout即标准输出,out_stdout将收到的日志事件打印到标准输出. 如果Fluentd以daemon方式在后台运行,out_stdout会将事件输出到Fluentd的运行日志中. 这个插件在 ...

  4. day05-离线留言和离线文件

    多用户即时通讯系统05 4.编码实现04(拓展) 拓展功能: 实现离线留言,如果某个用户不在线 ,当登陆后,可以接收离线的消息 实现离线发文件,如果某个功能没有在线,当登录后,可以接收离线的文件 4. ...

  5. 【前端必会】单页应用-你的新朋友wepack

    背景 我们开发的功能可能是简单的,但是实现功能的代码行数却可能成千上万 出于易于维护.安全.服用,我们会根据我们的经验设计我们的代码,拆解成多个独立的功能模块(代码片段.更多的文件) JS的模块规范有 ...

  6. Linux+Wine玩火影忍者究极风暴3指南

    如果你的系统没有Wine先装Wine,Wine在各大发行版的源都能找到.记住32位和64位的Wine都要装 去https://www.playonlinux.com/wine/binaries/pho ...

  7. [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT

    题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...

  8. C#-11 接口

    一 什么是接口 接口是指定一组函数成员而不实现它们的引用类型. class Program { static void FlyFunc(IFly obj) { obj.Fly(); } static ...

  9. Redis核心设计原理(深入底层C源码)

    Redis 基本特性 1. 非关系型的键值对数据库,可以根据键以O(1) 的时间复杂度取出或插入关联值 2. Redis 的数据是存在内存中的 3. 键值对中键的类型可以是字符串,整型,浮点型等,且键 ...

  10. centos7系统资源限制整理

    概述 在linux系统使用过程中,默认的系统设置足够使用,但是对于一些高并发高性能的程序会有瓶颈存在,这些限制主要通过ulimit查看和修改. 环境 centos:CentOS  release 7. ...