并发工具类(四)线程间的交换数据 Exchanger
前言
JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch、CyclicBarrier、Semphore、Exchanger、Phaser;
CountDownLatch、CyclicBarrier、Semphore、Phaser 这四个工具类提供一种并发流程的控制手段;而Exchanger工具类则提供了在线程之间交换数据的一种手段。
简介
Exchanger的功能是使2个线程之间交换数据(有不少文章的说法是“传输数据”,应该叫“交换数据”更合适,因为这是两个线程都要向对方传送数据,同时也获取对方的传送过来的数据,是
,并不是一个线程向另一个线程传输数据)。它比生产者/消费者模式使用的wait/notify要更加方便。
Exchanger 提供一个同步点,在这个同步点处,两个线程可以交换彼此数据。即一个线程调用了exchange( )方法交换数据,到达了同步点,然后就会一直阻塞等待另一个线程调用exchange( )方法来交换数据。所以,要注意
Exchanger 可能在应用程序(比如
)中很有用。
方法摘要
public V exchange(V x) throws InterruptedException
等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对
@ Example1 用法示例
以下是重点介绍的一个类,该类使用 Exchanger 在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程
class FillAndEmpty {Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();DataBuffer initialEmptyBuffer = ... a made-up typeDataBuffer initialFullBuffer = ...class FillingLoop implements Runnable {public void run() {DataBuffer currentBuffer = initialEmptyBuffer;try {while (currentBuffer != null) {addToBuffer(currentBuffer);if (currentBuffer.isFull())currentBuffer = exchanger.exchange(currentBuffer);}} catch (InterruptedException ex) { ... handle ... }}}class EmptyingLoop implements Runnable {public void run() {DataBuffer currentBuffer = initialFullBuffer;try {while (currentBuffer != null) {takeFromBuffer(currentBuffer);if (currentBuffer.isEmpty())currentBuffer = exchanger.exchange(currentBuffer);}} catch (InterruptedException ex) { ... handle ...}}}void start() {new Thread(new FillingLoop()).start();new Thread(new EmptyingLoop()).start();}}
复制代码
@ Example2 应用场景示例
Exchanger可以用于
Exchanger也可以用于
比如我们需要将纸制银流通过人工的方式录入成电子银行流水,为了避免错误,采用AB岗两人进行录入,录入到Excel之后,系统需要加载这两个Excel,并对这两个Excel数据进行校对,看看是否录入的一致。代码如下:
private static final Exchanger<String> exgr = new Exchanger<String>();
private static ExecutorService threadPool = Executors.newFixedThreadPool(2);public static void main(String[] args) {threadPool.execute(new Runnable() {@Overridepublic void run() {try {String A = "银行流水A";// A录入银行流水数据exgr.exchange(A);//同步点,交换数据} catch (InterruptedException e) {}}});threadPool.execute(new Runnable() {@Overridepublic void run() {try {String B = "银行流水B";// B录入银行流水数据String A = exgr.exchange("B");//同步点,交换数据System.out.println("A和B数据是否一致:" + A.equals(B) + "\nA录入的是:"+ A + "\nB录入的是:" + B);} catch (InterruptedException e) {}}});threadPool.shutdown();
}
复制代码
运行结果:
A和B数据是否一致:false
A录入的是:银行流水A
B录入的是:银行流水B
复制代码
文章源地址:https://www.cnblogs.com/jinggod/p/8494384.html
并发工具类(四)线程间的交换数据 Exchanger相关推荐
- 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...
- 并发工具类【线程安全相关的类】
1.Hashtable和ConcurrentHashMap Hashtable:哈希表结构(数组+链表),线程安全的(同步代码块,效率低) ConcurrentHashMap: jdk7:采用Segm ...
- 线程间怎么交换数据_2 万字长文详解 10 大多线程面试题|原力计划
作者 | ZZZhonngger 责编 | 伍杏玲 出品 | CSDN博客 Volatile相关 1.请谈谈你对 volatile 的理解 答:volatile 是 Java 虚拟机提供的轻量级的同步 ...
- 常用并发工具类(线程池)
文章目录 概述 ThreadPoolExecutor ThreadPoolExecutor 的主要属性 Worker 主要属性 线程池的状态 线程池的状态流转 线程池提交任务的执行流程 线程数量的设置 ...
- 线程池、volatile、原子性、并发工具类
目录 线程状态 线程池-基本原理 线程池 - Executors默认线程池 线程池 - ThreadPoolExecutor 线程池参数-拒绝策略 volatile 原子性 原子性 - AtomicI ...
- Java并发指南9:AQS共享模式与并发工具类的实现
一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...
- 并发工具类(四)两个线程进行数据交换的Exchanger
简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...
- 常用并发工具类(锁和线程间通信工具类)
常用并发工具类总结 JUC 下的常用并发工具类(锁和线程间通信工具类),主要包括 ReentrantLock.ReentrantReadWriteLock.CountDownLatch.CyclicB ...
- 第十章_多线程(2)_线程池原子性并发工具类
目录 一.线程池 1 - 线程状态 2 - 线程池 3 - Executors线程池 二.Volatile 三.原子性 四.并发工具类 1 - 并发工具类-Hashtable 2 - 并发工具类-Co ...
最新文章
- DataSet 动态添加列
- Android中关于SQLite数据库的一些知识
- Firefox3.0火速前进 比2.0版快2到3倍
- 无约束优化算法——牛顿法与拟牛顿法(DFP,BFGS,LBFGS)
- Kafka学习之四 Kafka常用命令
- 吴军《智能时代》序言汉译英练习
- matlab程序 surf算法,【求大神帮忙,surf算法源代码解析】
- HBase架构设计及原理分析
- 如何查看正在使用端口号并利用任务管理器将其关闭
- Tensorflow实现数据分档操作
- centos7.4装mysql_CentOS7.4用yum安装并配置MySQL5.7
- 汇编语言编写程序从1加到100要求使用循环结构。
- 5G技术演进与核心技术一(笔记)
- Faster RER-CNN 论文笔记
- 石川 :学术界、管理人、投资者视角下的因子投资
- ISIS-广播网络DIS更新LSDB
- python白噪声检验结果查询_使用python实现时间序列白噪声检验方式
- 地热井监测控制系统解决方案
- HTML+CSS练习案例
- 一文讲透:质量管理的历史
热门文章
- ubuntu16.04 安装 ipython
- 设△ABC的内角A,B,C,所对的边分别为a,b,c,且acosB-bcosA=3/5c,则tan(A-B)的最大值为
- gradle各版本下载地址
- Rsync:一个很实用的文件同步命令
- Akka(9): 分布式运算:Remoting-远程构建式
- (原)直方图的相似性度量
- Emule使用Upnp,解决Lowid和port not reachable的问题
- Singleton patterns 单件(创建型模式)
- 十天学会ASP.Net——(8)
- STM32使用SPI通信驱动2.4G无线射频模块发送数据