【JUC】交换器Exchanger详解
欢迎关注专栏【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,
- A线程交换数据时,发现slot为空,则将需要交换的数据放在slot中, 阻塞当前线程,等待其它线程进来交换数据
- 等线程B进来,读取A设置的数据,然后设置线程B需要交换的数据,然后唤醒A线程。
Exchanger的源码实现大家感兴趣的话,自己可以看看。
总结
本文讲解了交换器Exchanger,是jdk5中引入的一个同步器。实际上在平时工作场景中基本上很少应用,按照官方注释说可以应用在基因算法或者管道设计,太抽象了,大家就当扩扩知识面吧。
如果本文对你有帮助的话,请留下一个赞吧
【JUC】交换器Exchanger详解的更多相关文章
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
- 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术
这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...
- java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService
这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...
- JUC中的AQS底层详细超详解
摘要:当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒? 本文分享自华为云社区<JUC中的AQS底层详细超详解,剖 ...
- 多线程之 Final变量 详解
原文: http://www.tuicool.com/articles/2Yjmqy 并发编程网:http://ifeve.com/java-memory-model/ 总结: Final 变量在并发 ...
- Dubbo架构设计详解-转
Dubbo架构设计详解 2013-09-03 21:26:59 Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...
- java并发包java.util.concurrent详解
线程池ThreadPoolExecutor的使用 并发容器之CopyOnWriteArrayList 并发容器之CopyOnWriteArraySet 数据结构之ConcurrentHashMap,区 ...
- (转)Java并发包基石-AQS详解
背景:之前在研究多线程的时候,模模糊糊知道AQS这个东西,但是对于其内部是如何实现,以及具体应用不是很理解,还自认为多线程已经学习的很到位了,贻笑大方. Java并发包基石-AQS详解Java并发包( ...
- .Net使用RabbitMQ详解 转载http://www.cnblogs.com/knowledgesea/p/5296008.html
.Net使用RabbitMQ详解 序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其 ...
- HAProxy详解(一):HAProxy介绍【转】
一.高性能负载均衡软件HAProxy介绍: 随着互联网业务的迅猛发展,大型电商平台和门户网站对系统的可用性和可靠性要求越来越高,高可用集群.负载均衡集群成为一种热门的系统架构解决方案.在众多的负载均衡 ...
随机推荐
- 3.Ceph 基础篇 - RBD 块存储使用
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485253&idx=1&sn=24d9b06a ...
- 现有rabbitmq集群添加新节点,移除旧节点(可以作为rabbitmq集群迁移使用)
原有集群安装步骤:https://www.cnblogs.com/sanduzxcvbnm/p/15797788.html 1.拉取镜像 集群中新节点需要执行 docker pull rabbitmq ...
- Fielddata is disabled on text fields by default Set fielddata=true on [service.address]
2个字段的: PUT metricbeat-7.3.0/_mapping { "properties": { "service": { "proper ...
- 使用Recoding Rules优化性能
通过PromQL可以实时对Prometheus中采集到的样本数据进行查询,聚合以及其它各种运算操作.而在某些PromQL较为复杂且计算量较大时,直接使用PromQL可能会导致Prometheus响应超 ...
- slf4j、log4j2及logback使用
slf4j.log4j2及logback使用 1.问题来源 之前看过关于slf4j.log4j2及logback的介绍,slf4j是门面,log4j2及logback是具体实现,仅使用slf4j门面是 ...
- 使用 HammerDB 对 Citus 和 Postgres 进行 Benchmark,每分钟200万新订单处理测试(官方博客)
在为 Postgres 运行性能基准测试时,主要建议是:"自动化!" 如果您正在测量数据库性能,您可能不得不一遍又一遍地运行相同的基准测试. 要么是因为你想要一个稍微不同的配置,要 ...
- CPS攻击案例(一)——基于脉冲宽度调制PWM的无人机攻击
本文系原创,转载请说明出处 Please Subscribe Wechat Official Account:信安科研人,获取更多的原创安全资讯 原论文链接:sec22-dayanikli.pd ...
- HDU4991 Ordered Subsequence (树状数组优化DP)
dp[i][j]表示以a[i]结尾的长度为j的上升子序列个数. 方程:dp[i][j]=sum(dp[k][j-1]),a[k]<a[i],1<=k<i. 求解目标:sum(dp[k ...
- 程序员便于开发的一些工具、网站、App。
http://www.kancloud.cn 关于文档,各种技术,框架的学习指南,API文档搜索方便. https://leetcode.com/ 程序员刷题面试网站,无聊的时候可以做一做.
- 一篇文章让你搞懂Java中的静态代理和动态代理
什么是代理模式 代理模式是常用的java设计模式,在Java中我们通常会通过new一个对象再调用其对应的方法来访问我们需要的服务.代理模式则是通过创建代理类(proxy)的方式间接地来访问我们需要的服 ...