thread_Exchanger数据交换
Exchanger 是一个同步辅助类,用于两个并发线程之间在一个同步点进行数据交换。
允许两个线程在某一个点进行数据交换。
可以视作双向的同步队列;
可应用于基因算法、流水线设计等场景
Exchanger提供了 一个同步点 , 在这个同步点,两个线程可以交换数据 。每个线程通过exchange()方法的入口提供数据给另外的线程,并接收其它线程提供的数据,并返回。
public class Exchanger1Test { // 场景描述:一对一的 生产者和消费者,生产者每次生产5个商品,然后消费者把空的商品容器和生产者交换。
// 生产者线程一定要先生产数据,再交换数据,消费者线程一定要先交换数据,再消费数据,否则会出现少消费数据的现象
// 允许原子性的交换两个(多个)对象,但同时只有一对才会成功
// exchange方法真的帮一对线程交换了数据;
// exchange方法真的会阻塞调用方线程直至另一方线程参与交易。
public static void main(String[] args) { // Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。
// 两个线程必须使用同一个Exchanger对象,且只能是两个线程间的数据交换
// 当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行
Exchanger<ArrayList<String>> exchanger = new Exchanger<ArrayList<String>>();
ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new Producer(exchanger));
exec.execute(new Consumer(exchanger));
exec.shutdown();
try {
exec.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// log.error(e, e);
}
}
} // 生产者
class Producer implements Runnable {
private ArrayList<String> goods = new ArrayList<String>(); // 商品容器
private Exchanger<ArrayList<String>> exchanger = new Exchanger<ArrayList<String>>();
//控制交易双方线程的退出
private static AtomicBoolean isDone = new AtomicBoolean(true);
public Producer(Exchanger<ArrayList<String>> exchanger) {
this.exchanger = exchanger;
} @Override
public void run() {
while (!Thread.interrupted() && isDone.get()) {// for (int i = 0; i < 3; i++) { // 生产3次
System.out.println("------------------------生产者生产第 " + i + "次");
for (int j = 0; j < 3; j++) { // 每次生产3个商品
String e = (long) (Math.random() * 1000) + "";
goods.add(e);
System.out.println("生产了商品:" + e);
}
try {
// 生产者线程一定要先生产数据,再交换数据,消费者线程一定要先交换数据,再消费数据
// exchanger.exchange(v)的时候,当前线程会被阻塞,直到另一个线程执行该方法,同时完成数据的交换
goods = exchanger.exchange(goods); // 交换数据
System.out.println("生产者:数据交换完毕:获得交换的商品容器大小:" + goods.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} // 消费者
class Consumer implements Runnable {
private ArrayList<String> goods = new ArrayList<String>(); // 商品容器
private Exchanger<ArrayList<String>> exchanger = new Exchanger<ArrayList<String>>();
private static AtomicBoolean isDone = new AtomicBoolean(true);
public Consumer(Exchanger<ArrayList<String>> exchanger) {
this.exchanger = exchanger;
} @Override
public void run() {
while (!Thread.interrupted() && isDone.get()) {//&& !isDone
for (int i = 0; i < 3; i++) { // 消费3次
try {
// 生产者线程一定要先生产数据,再交换数据,消费者线程一定要先交换数据,再消费数据
// exchanger.exchange(v)的时候,当前线程会被阻塞,直到另一个线程执行该方法,同时完成数据的交换
goods = exchanger.exchange(goods); // 交换数据
System.out.println("消费者:数据交换完毕:获得交换的商品容器大小:" + goods.size()); // 消费商品
Iterator<String> it = goods.iterator();
if (goods.size() > 0) {
System.out.println("*********************消费者消费第 " + i + "次");
while (it.hasNext()) {
String next = it.next();
System.out.println("消费了商品:" + next);
it.remove(); // 移除消费了的商品
}
} } catch (InterruptedException e) {
e.printStackTrace();
}
} }
}
}
thread_Exchanger数据交换的更多相关文章
- Android:Activity+Fragment及它们之间的数据交换.
Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...
- Atitit.常见软件 数据 交换格式 标准
Atitit.常见软件 数据 交换格式 标准 1. 常见的数据格式txt ,doc ,pic,music ,vodio1 2. 通用格式json yaml phpstr1 3. 专用格式1 4. 用户 ...
- Js中JSON数据交换使用总结
Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...
- Java--Exchanger用于进行线程间的数据交换
package com; import java.util.concurrent.Exchanger; /** * Created by yangyu on 16/11/28. */ /** * Ex ...
- 【AS3】Flash与后台数据交换四种方法整理
随着Flash Player 9的普及,AS3编程也越来越多了,所以这次重新整理AS3下几种与后台数据交换方法.1.URLLoader(URLStream)2.FlashRemoting3.XMLSo ...
- JQuery + XML作为前后台数据交换格式实践
JQuery + xml作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ xml作为一种 ...
- JQuery + JSON作为前后台数据交换格式实践
JQuery + JSON作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ JSON作为 ...
- Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger
本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...
- java5 Exchanger数据交换
Java并发API提供了一种允许2个并发任务间相互交换数据的同步应用.更具体的说,Exchanger类允许在2个线程间定义同步点,当2个线程到达这个点,他们相互交换数据类型,使用第一个线程的数据类型变 ...
随机推荐
- MongoDB副本集配置系列九:MongoDB 常见问题
What is a namespace in MongoDB? If you remove a document, does MongoDB remove it from disk? When doe ...
- HLS视频点播&直播初探
前端可选的视频直播协议大致只有两种: RTMP(Real Time Messaging Protocol) HLS(HTTP Live Streaming) 其中RTMP是Adobe开发的协议,无法在 ...
- Javascript的一个生产PDF的库: unicode和中文问题的解决
Javascript的一个生产PDF的库: unicode和中文问题的解决基于canvas和jspdf库, 实现用javascript的支持中文pdf生成实用工具.参考:http://javascri ...
- 【C#】取得并改变图像解析度
, , bmpOrg.Width, bmpOrg.Height); g.Dispose(); // 画像を保存 string dirName = Path.GetD ...
- JRE_HOME environment variable is not defined correctly This environment variableis needed to run this program
已经安装了JDK1.7 和对应JRE 安装了tomcat8 都是解压版 并设置了JAVA_HOME.JRE_HOME 但Tomcat在启动过程中找不到 错误: the JRE_HOME environ ...
- 用Jquery load text文本到網頁遇到的問題
HTML <div id="divText"></div> Javascript $('#divText').load(fileName ,function ...
- SQL语句转摘
http://www.cnblogs.com/Olive116/p/3271706.html 收藏没有用,来收到留链接
- 使用 crosswalk-cordova 打包sencha touch 项目,再也不用担心安卓兼容问题!
国内的安卓手机品牌众多,安卓操作系统碎片化也很严重,我们使用sencha touch 开发的应用不可避免的出现了各种无解的兼容性问题. 有时候我就在想,有没有既能支持cordova,又能让我们把Chr ...
- U盘FAT32转换NTFS格式
运行----cmd----convert x:/fs:ntfs回车 x标识你的U盘或硬盘盘符 比如你的U盘是H盘,那就是h:/fs:ntfs FAT32----NTFS是不可逆转的转换.
- 写给已有编程经验的 Python 初学者的总结
当我开始学习Python的时候,有些事我希望我一早就知道.我花费了很多时间才学会这些东西.我想要把这些重点都编纂到一篇文章当中.这篇文章的目标读者,是刚刚开始学习Python语言的有经验的程序员,想要 ...