面试突击49:说一下 JUC 中的 Exchange 交换器?
Exchange(交换器)顾名思义,它是用来实现两个线程间的数据交换的,它诞生于 JDK 1.5,它有两个核心方法:
- exchange(V x):等待另一个线程到达此交换点,然后将对象传输给另一个线程,并从另一个线程中得到交换的对象。如果另一个线程未到达此交换点,那么此线程会一直休眠(除非遇了线程中断)。
- exchange(V x, long timeout, TimeUnit unit):等待另一个线程到达此交换点,然后将对象传输给另一个线程,并从另一个线程中得到交换的对象。如果另一个线程未到达此交换点,那么此线程会一直休眠,直到遇了线程中断,或等待的时间超过了设定的时间,那么它会抛出异常。
也就是说 exchange 方法就是一个交换点,线程会等待在此交换点,直到有另一个线程也调用了 exchange 方法(相当于进入到了此交换点),这时他们会互换数据,然后执行后续的代码。
基础使用
Exchange 的基础使用如下,我们创建两个线程来模拟“一手交钱、一手交货”的场景,线程 1 先准备好钱进入交换点,然后等待线程 2 在 2s 之后准备好货(物),之后再彼此交互数据,执行后续的流程,具体实现代码如下:
import java.time.LocalDateTime;
import java.util.concurrent.Exchanger;
public class ExchangeExample {
// 创建一个交互器
private final static Exchanger<String> exchange = new Exchanger<>();
public static void main(String[] args) {
// 线程 1【准备钱】
new Thread(() -> {
System.out.println("线程1:准备筹钱中...| Time:" + LocalDateTime.now());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String moeny = "1000 万";
System.out.println("线程1:钱准备好了【1000 万】。| Time:" +
LocalDateTime.now());
try {
// 执行数据交换【交易】
String result = exchange.exchange(moeny);
System.out.println("线程1:交易完成,得到【" + result +
"】 | Time:" + LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 线程 2【准备货】
new Thread(() -> {
System.out.println("线程2:准备物品中【西伯利亚新鲜空气】...| Time:" +
LocalDateTime.now());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String goods = "西伯利亚新鲜空气";
System.out.println("线程2:物品准备好了【西伯利亚新鲜空气】。| Time:" +
LocalDateTime.now());
try {
// 执行数据交换【交易】
String result = exchange.exchange(goods);
System.out.println("线程2:交易完成,得到【" + result +
"】 | Time:" + LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
以上程序的执行结果如下:

总结
Exchange 交换器是用来实现两个线程间的数据交换的,Exchanger 可以交互任意数据类型的数据,只要在创建的时候定义泛型类型即可。它的核心方法为 exchange,当线程执行到此方法之后,会休眠等待另一个线程也进入交换点,如果另一个线程也进入了交换点(也执行到了 exchange 方法),此时二者会交换数据,并执行后续的流程。
是非审之于己,毁誉听之于人,得失安之于数。
公众号:Java面试真题解析
面试突击49:说一下 JUC 中的 Exchange 交换器?的更多相关文章
- 面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频
1 考察知识点 本题考察的知识点有以下几个: Keys 和 Scan 的区别 Keys 查询的缺点 Scan 如何使用? Scan 查询的特点 2 解答思路 Keys 查询存在的问题 Scan 的使用 ...
- 《【面试突击】— Redis篇》--Redis都有哪些数据类型?分别在哪些场景下使用比较合适?
能坚持别人不能坚持的,才能拥有别人不能拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>--Redis都有哪些数据类型?分别在哪些场景下使用 ...
- 《【面试突击】— Redis篇》-- Redis的线程模型了解吗?为啥单线程效率还这么高?
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的线程模型了解吗?为啥单线程效率还这 ...
- 《【面试突击】— Redis篇》-- Redis的主从复制?哨兵机制?
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注左上角编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的主从复制?哨兵机制? 在这个 ...
- 《【面试突击】— Redis篇》-- Redis哨兵原理及持久化机制
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis哨兵原理及持久化机制 在这个系列里, ...
- 《【面试突击】— Redis篇》--Redis Cluster及缓存使用和架构设计的常见问题
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>--Redis Cluster及缓存使用和架构设计的 ...
- JUC学习笔记--JUC中并发工具类
JUC中并发工具类 CountDownLatch CountDownLatch是我目前使用比较多的类,CountDownLatch初始化时会给定一个计数,然后每次调用countDown() 计数减1, ...
- 基于接口回调详解JUC中Callable和FutureTask实现原理
Callable接口和FutureTask实现类,是JUC(Java Util Concurrent)包中很重要的两个技术实现,它们使获取多线程运行结果成为可能.它们底层的实现,就是基于接口回调技术. ...
- JUC集合之 JUC中的集合类
Java集合包 在"Java 集合系列01之 总体框架"中,介绍java集合的架构.主体内容包括Collection集合和Map类:而Collection集合又可以划分为List( ...
随机推荐
- js技术之分割split()
案例:把所有单词以空格为分割并将首字母转为大写 <!DOCTYPE html><html lang="en"><head> <meta c ...
- Matplotlib is currently using agg, which is a non-GUI backend 和 ImportError: No module named 'Tkinter' [closed]
跑maskrcnn报错:UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot sh ...
- can总线第二讲
一 CAN总线拓扑结构CAN是一种分布式的控制总线,总线上的每一个节点一般来说都比较简单,使用MCU控制器处理CAN总线数据,完成特定的功能:通过CAN总线将各节点连接只需较少的线缆(两根线:CAN_ ...
- 玩转 React(四)- 创造一个新的 HTML 标签
在第二篇文章 <新型前端开发方式> 中有说到 React 有很爽的一点就是给我们一种创造 HTML 标签的能力,那么今天这篇文章就详细讲解下 React 是如何提供这种能力的,作为前端开发 ...
- SphinxJS——把字符串编码成png图片的超轻量级开源库
体验地址:https://jrainlau.github.io/sp...项目地址:https://github.com/jrainlau/s... SphinxJS 一个能够把字符串编码成png图片 ...
- 【Android开发】jarsigner重新打包apk
签名(sign):在应用程序的特定字段写入特定的标记信息,表示该软件已经通过了签署者的审核. 过程:使用私有密钥数字地签署一个给定的应用程序. 作用: 识别应用程序作者: 检測应用程序是否发生改变: ...
- 利用css3实现3D轮播图
动画实现主要利用了z-index将层级关系改变,从而实现了焦点图的效果:css3属性 transform rotate 来实现图片的动画效果 .transition实现过度动画! * { margin ...
- phpshe xml注入
*php商城系统 xml注入* **页面样式* *Xml原理参考:* https://www.cnblogs.com/20175211lyz/p/11413335.html *漏洞函数simplexm ...
- python---快速排序的实现
def quick_sort(alist, start, end): """快速排序""" # 递归退出 if start >= en ...
- FSB—QPI—DMI总线的发展
intel CPU有的是前端总线(FSB),有的是QPI总线,有的又是DMI总线 FSB总线(由于cpu的发展,fsb总线制约了cpu的发展,所以该总线已经渐渐淡出历史舞台) FSB即Front Si ...