前言

  JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch、CyclicBarrier、Semphore、Exchanger、Phaser;
  CountDownLatch、CyclicBarrier、Semphore、Phaser 这四个工具类提供一种并发流程的控制手段;而Exchanger工具类则提供了在线程之间交换数据的一种手段。

简介

   Exchanger的功能是使2个线程之间交换数据(有不少文章的说法是“传输数据”,应该叫“交换数据”更合适,因为这是两个线程都要向对方传送数据,同时也获取对方的传送过来的数据,是

双向模式

,并不是一个线程向另一个线程传输数据)。它比生产者/消费者模式使用的wait/notify要更加方便。
  Exchanger 提供一个同步点,在这个同步点处,两个线程可以交换彼此数据。即一个线程调用了exchange( )方法交换数据,到达了同步点,然后就会一直阻塞等待另一个线程调用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可以用于

遗传算法,遗传算法里需要选出两个人作为交配对象,这时候会交换两人的数据,并使用交叉规则得出2个交配结果。

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相关推荐

  1. 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)

    文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...

  2. 并发工具类【线程安全相关的类】

    1.Hashtable和ConcurrentHashMap Hashtable:哈希表结构(数组+链表),线程安全的(同步代码块,效率低) ConcurrentHashMap: jdk7:采用Segm ...

  3. 线程间怎么交换数据_2 万字长文详解 10 大多线程面试题|原力计划

    作者 | ZZZhonngger 责编 | 伍杏玲 出品 | CSDN博客 Volatile相关 1.请谈谈你对 volatile 的理解 答:volatile 是 Java 虚拟机提供的轻量级的同步 ...

  4. 常用并发工具类(线程池)

    文章目录 概述 ThreadPoolExecutor ThreadPoolExecutor 的主要属性 Worker 主要属性 线程池的状态 线程池的状态流转 线程池提交任务的执行流程 线程数量的设置 ...

  5. 线程池、volatile、原子性、并发工具类

    目录 线程状态 线程池-基本原理 线程池 - Executors默认线程池 线程池 - ThreadPoolExecutor 线程池参数-拒绝策略 volatile 原子性 原子性 - AtomicI ...

  6. Java并发指南9:AQS共享模式与并发工具类的实现

    一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...

  7. 并发工具类(四)两个线程进行数据交换的Exchanger

    简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...

  8. 常用并发工具类(锁和线程间通信工具类)

    常用并发工具类总结 JUC 下的常用并发工具类(锁和线程间通信工具类),主要包括 ReentrantLock.ReentrantReadWriteLock.CountDownLatch.CyclicB ...

  9. 第十章_多线程(2)_线程池原子性并发工具类

    目录 一.线程池 1 - 线程状态 2 - 线程池 3 - Executors线程池 二.Volatile 三.原子性 四.并发工具类 1 - 并发工具类-Hashtable 2 - 并发工具类-Co ...

最新文章

  1. DataSet 动态添加列
  2. Android中关于SQLite数据库的一些知识
  3. Firefox3.0火速前进 比2.0版快2到3倍
  4. 无约束优化算法——牛顿法与拟牛顿法(DFP,BFGS,LBFGS)
  5. Kafka学习之四 Kafka常用命令
  6. 吴军《智能时代》序言汉译英练习
  7. matlab程序 surf算法,【求大神帮忙,surf算法源代码解析】
  8. HBase架构设计及原理分析
  9. 如何查看正在使用端口号并利用任务管理器将其关闭
  10. Tensorflow实现数据分档操作
  11. centos7.4装mysql_CentOS7.4用yum安装并配置MySQL5.7
  12. 汇编语言编写程序从1加到100要求使用循环结构。
  13. 5G技术演进与核心技术一(笔记)
  14. Faster RER-CNN 论文笔记
  15. 石川 :学术界、管理人、投资者视角下的因子投资
  16. ISIS-广播网络DIS更新LSDB
  17. python白噪声检验结果查询_使用python实现时间序列白噪声检验方式
  18. 地热井监测控制系统解决方案
  19. HTML+CSS练习案例
  20. 一文讲透:质量管理的历史

热门文章

  1. ubuntu16.04 安装 ipython
  2. 设△ABC的内角A,B,C,所对的边分别为a,b,c,且acosB-bcosA=3/5c,则tan(A-B)的最大值为
  3. gradle各版本下载地址
  4. Rsync:一个很实用的文件同步命令
  5. Akka(9): 分布式运算:Remoting-远程构建式
  6. (原)直方图的相似性度量
  7. Emule使用Upnp,解决Lowid和port not reachable的问题
  8. Singleton patterns 单件(创建型模式)
  9. 十天学会ASP.Net——(8)
  10. STM32使用SPI通信驱动2.4G无线射频模块发送数据