java并发编程JUC第十一篇:如何在线程之间进行对等数据交换

java.util.concurrent.Exchanger可以用来进行数据交换,或者被称为“数据交换器”。两个线程可以使用Exchanger交换数据,下图用来说明Exchanger的作用

在下面的代码中
- 首先我们定义了一个Exchanger,用于数据交换
- 然后定义了两个线程对象bookExchanger1和bookExchanger2,两个线程都持有Exchanger交换器对象用于数据交换
- 两个线程中的每个线程都有自己的数据,比如下面代码中的String[] 书籍数组。
public static void main(String[] args) {
//数据交换器-数据为book
Exchanger<String> exchanger = new Exchanger<>();
//换书线程1
BookExchanger bookExchanger1
= new BookExchanger(exchanger, new String[]{"Java从入门到放弃","Java编程思想"});
//换书线程2
BookExchanger bookExchanger2
= new BookExchanger(exchanger, new String[]{"C语言程序设计","实战Python数据分析"});
new Thread(bookExchanger1).start();
new Thread(bookExchanger2).start();
}
BookExchanger 继承自Runnable代表参与换书的换书读者,他持有Exchanger数据交换器用于交换图书。
public class BookExchanger implements Runnable{
Exchanger<String> exchanger = null; //数据交换器
String[] books = null; //图书数组
public BookExchanger(Exchanger<String> exchanger, String[] books) {
this.exchanger = exchanger;
this.books = books;
}
@Override
public void run() {
try {
for(String bookName : books) {
//交换数据,bookName为我的书,exBook为我换回来的书
String exBook = this.exchanger.exchange(bookName);
System.out.println(
Thread.currentThread().getName() +
" 用《 " + bookName + "》 换 《 " + exBook + "》"
);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行上文中的代码,得到如下的打印输出。可以看到只有两个线程完成一次交换之后,才能再进行下一次的交换。
Thread-1 用《 C语言程序设计》 换 《 Java从入门到放弃》
Thread-0 用《 Java从入门到放弃》 换 《 C语言程序设计》
Thread-1 用《 实战Python数据分析》 换 《 Java编程思想》
Thread-0 用《 Java编程思想》 换 《 实战Python数据分析》
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
java并发编程JUC第十一篇:如何在线程之间进行对等数据交换的更多相关文章
- java并发编程JUC第十篇:CyclicBarrier线程同步
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程笔记(十一)——高并发处理思路和手段
java并发编程笔记(十一)--高并发处理思路和手段 扩容 垂直扩容(纵向扩展):提高系统部件能力 水平扩容(横向扩容):增加更多系统成员来实现 缓存 缓存特征 命中率:命中数/(命中数+没有命中数) ...
- java并发编程JUC第九篇:CountDownLatch线程同步
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- Java并发编程实战.笔记十一(非阻塞同步机制)
关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...
- Java 并发编程(四):如何保证对象的线程安全性
01.前言 先让我吐一句肺腑之言吧,不说出来会憋出内伤的.<Java 并发编程实战>这本书太特么枯燥了,尽管它被奉为并发编程当中的经典之作,但我还是忍不住.因为第四章"对象的组合 ...
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
依据<Java并发编程实践>一书整理的思维导图.
- Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)
前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...
- Java并发编程原理与实战五:创建线程的多种方式
一.继承Thread类 public class Demo1 extends Thread { public Demo1(String name) { super(name); } @Override ...
- Java并发编程(一):进程和线程之由来
转自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当 ...
随机推荐
- [C#] 使用 NAudio 实现音频可视化
预览: 捕捉声卡输出: 实现音频可视化, 第一步就是获得音频采样, 这里我们选择使用计算机正在播放的音频作为采样源进行处理: NAudio 中, 可以借助 WasapiLoopbackCapture ...
- Mac/Win录屏工具推荐-LICEcap
轻小.便捷.操作简单 下载 LICEcap v1.30 for macOS LICEcap v1.28 for Windows 参考地址
- 【实用小技巧】Access denied for user 'root'@'localhost' 报错解决
到mysql安装目录修改my.ini文件,在文件末尾追加一句 skip-grant-tables 然后重启mysql服务即可
- Asp.NetCore Web开发之创建项目
这一节,开始讲一下如何创建一个Asp.netCore Web项目,有两种常用的方式,一种是通过.NetCore SDK使用命令创建,另一种如果你使用的VisualStudio,可以直接根据引导创建. ...
- 使用DevExpress的GridControl实现多层级或无穷级的嵌套列表展示
在我早期的随笔<在GridControl表格控件中实现多层级主从表数据的展示>中介绍过GridControl实现二级.三级的层级列表展示,主要的逻辑就是构建GridLevelNode并添加 ...
- 改善c++程序的150个建议(读后总结)-------27-35
27. 区分内存分配的方式 c++中内存分为5个不同的区 ①栈区 栈是一种特殊的数据结构,其存取数据特点为(先进后出,后进先出).栈区中主要用于存储一些函数的入口地址,函数调用时的实参值以及局部变量. ...
- 理解微信小程序的双线程模型
有过微信小程序开发经验的朋友应该都知道"双线程模型"这个概念,本文简单梳理一下双线程模型的一些科普知识,学识浅薄,若有错误欢迎指正. 我以前就职于「小程序·云开发」团队,在对外的一 ...
- OAuth2.0 授权方式及步骤梳理总结
OAuth 2.0授权协议使第三方应用程序可以通过协调资源所有者和HTTP服务之间的批准交互,或者通过允许第三方应用程序代表资源所有者来获得对HTTP服务的有限访问权,或者代表资源所有者. 代表自己获 ...
- CSS中常用的函数
一.CSS函数的用法 设置css的属性值时可以使用css函数,如果color:rgba(20,30,50,0.5),css中有很多这样的函数. 二.常用的CSS函数 a.calc()函数 这个函数 ...
- JavaScript中的运算符和语句
一.JavaScript的运算符 a.基本的算术运算符(+.-.*./.%) -.*./.%运算符会在必要的时候将操作数转换为数字,无法转换成数字的操作数将会转换成NaN,相应的运算结果也是NaN. ...