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数据交换的更多相关文章

  1. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  2. Atitit.常见软件 数据 交换格式 标准

    Atitit.常见软件 数据 交换格式 标准 1. 常见的数据格式txt ,doc ,pic,music ,vodio1 2. 通用格式json yaml phpstr1 3. 专用格式1 4. 用户 ...

  3. Js中JSON数据交换使用总结

    Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...

  4. Java--Exchanger用于进行线程间的数据交换

    package com; import java.util.concurrent.Exchanger; /** * Created by yangyu on 16/11/28. */ /** * Ex ...

  5. 【AS3】Flash与后台数据交换四种方法整理

    随着Flash Player 9的普及,AS3编程也越来越多了,所以这次重新整理AS3下几种与后台数据交换方法.1.URLLoader(URLStream)2.FlashRemoting3.XMLSo ...

  6. JQuery + XML作为前后台数据交换格式实践

    JQuery + xml作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ xml作为一种 ...

  7. JQuery + JSON作为前后台数据交换格式实践

    JQuery + JSON作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ JSON作为 ...

  8. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

  9. java5 Exchanger数据交换

    Java并发API提供了一种允许2个并发任务间相互交换数据的同步应用.更具体的说,Exchanger类允许在2个线程间定义同步点,当2个线程到达这个点,他们相互交换数据类型,使用第一个线程的数据类型变 ...

随机推荐

  1. [Aaronyang]谈谈2015年AY对WPF全面技术总结40多篇WPF,炫到没朋友的AYUI来了

             原著:AY WPF博客- 把wpf推广出去,让那些鄙视的人说不 大家好! 我是AY,首先声明,我在做一件很枯燥的事情,我是个91后程序员,每天熬夜完成计划的过着下班后的生活. 那天有 ...

  2. hive中同列多行数据组合的方法以及array to string要点(行转列)

    1. 同列多行数据组合成一个字段cell的方法, top N 问题的hive方案 如下: hive 列转行 to json与to array list set等复杂结构,hive topN的提取的窗口 ...

  3. javascript - 二叉树

    都是些简单的东西,所以直接上代码了. /** * Created by huangjacky on 14-10-3. */ function Node(element, left, right) { ...

  4. 移动应用安全开发指南(Android)--完结篇(http://www.bubuko.com/infodetail-577312.html)

    1.认证和授权 概述 认证是用来证明用户身份合法性的过程,授权是用来证明用户可以合法地做哪些事的过程,这两个过程一般是在服务器端执行的,但也有的APP出于性能提升或用户体验等原因,将其做在客户端完成, ...

  5. 在 Excel 中使用正则表达式进行查找与替换

    在 Excel 中,使用 Alt+F11 快捷键打开 VBA 项目窗口,在左侧的工作表名称上点右键,选择查看代码,即可出出现右侧的代码编辑窗口 在代码窗口中输入以下代码: Private Sub Re ...

  6. iOS开发——项目实战总结&经典错误一

    经典错误一 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7, VA 运行报错 出现的原因:armv7s ...

  7. php连接oracle数据库的方法

    1.在php.ini中打开extension=php_oci8扩展,重启服务. 2.将php/ext目录下的php_oci8.dll文件拷贝到system32目录下 3.安装 Oracle9i客户端精 ...

  8. struts2:JSP页面及Action中获取HTTP参数(parameter)的几种方式

    本文演示了JSP中获取HTTP参数的几种方式,还有action中获取HTTP参数的几种方式. 1. 创建JSP页面(testParam.jsp) <%@ page language=" ...

  9. iis,w3wp一直出现WerFault.exe应用程序错误

    这个进程是Windows错误报告技术里的一个东西,来收集软件崩溃或者挂起后的数据然后向微软反馈报告.关闭系统的错误报告功能后看看 1:打开 运行 (热键:win+R)输入 gpedit.msc 打开  ...

  10. LoadRunner11.52发布,全新的VTS

    LoadRunner11.52发布,全新的VTShttp://automationqa.com/forum.php?mod=viewthread&tid=2252&fromuid=2 ...