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个线程到达这个点,他们相互交换数据类型,使用第一个线程的数据类型变 ...
随机推荐
- WPF 获取程序路径的一些方法,根据程序路径获取程序集信息
一.WPF 获取程序路径的一些方法方式一 应用程序域 //获取基目录即当前工作目录 string str_1 = System.AppDomain.CurrentDomain.BaseDirector ...
- SQL的主键和外键约束
SQL的主键和外键的作用: 外键取值规则:空值或参照的主键值. (1)插入非空值时,如果主键表中没有这个值,则不能插入. (2)更新时,不能改为主键表中没有的值. (3)删除主键表记录时,你可以在建外 ...
- Windows2008 R2下,DCOM配置里的属性灰色不可用的解决方法
错误为:为应用程序池“XXXXXX”提供服务的进程在与“Windows Process Activation Service”通信时出现严重错误.该进程 ID 为"XXX".数据字 ...
- 解决CSS移动端1px边框问题
移动项目开发中,安卓或者IOS等高分辨率屏幕会把1px的border渲染成2px来显示,网上搜了一下,解决方法如下: 一.利用css中的transform的缩放属性解决,推荐这个.如下面代码. < ...
- TabHost的用法(转)
本文结合源代码和实例来说明TabHost的用法. 使用TabHost 可以在一个屏幕间进行不同版面的切换,例如android自带的拨号应用,截图: 查看tabhost的源代码,主要实例变量有: pr ...
- Session机制详解
转自:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能 ...
- ODAC(V9.5.15) 学习笔记(十五)数据离线模式
数据离线模式(Disconnected Mode)是指数据库只有在需要的时候才连接,数据的处理放在客户端内存缓冲区中完成.这样做最大的好处是减少了网络资源依赖,对数据库服务器的资源开销和压力也减少.如 ...
- Android Studio配置和使用OpenCV3.x,不需要OpencvManager
转载声明,本文转自CSDN:http://blog.csdn.net/qq_22033759/article/details/51156121 ps:本来在贴吧上有人问,想自己写的,但时间有限,当初自 ...
- ruby中字符的转换
1.将表格名转成class名 classify "book_comments".classify => "BookComment" 2.class名转 ...
- Java知多少(完结篇)
Java知多少(1)语言概述 Java知多少(2)虚拟机(JVM)以及跨平台原理 Java知多少(3) 就业方向 Java知多少(4)J2SE.J2EE.J2ME的区别 Java知多少(5) Java ...