并发工具类(四)线程间的交换数据 Exchanger
来源:互联网 发布:windows snmptools 编辑:程序博客网 时间:2024/05/21 06:17
前言
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 type DataBuffer 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() { @Override public void run() { try { String A = "银行流水A";// A录入银行流水数据 exgr.exchange(A);//同步点,交换数据 } catch (InterruptedException e) { } } }); threadPool.execute(new Runnable() { @Override public 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
文献:
- 《java并发编程的艺术》
- JAVA中的并发工具类(四)---线程间交换数据的Exchanger类
- 并发工具类(四)线程间的交换数据 Exchanger
- java 线程间交换数据的Exchanger
- Exchanger:线程交换数据
- Exchanger数据交换工具
- 线程并发工具--Exchanger
- Exchanger两个线程之间的数据交换
- 两个线程进行数据交换的Exchanger
- 控制并发线程数的Semaphore和线程之间的数据交换Exchanger
- Exchanger: 两个线程 间 交换 数据
- Exchanger用于线程间交换数据
- Java Exchanger(两线程交换数据)
- Java线程总结(十):并发包------两个线程交换数据Exchanger
- Java多线程/并发25、Exchanger线程数据交换
- Java中使用Exchanger类进行线程间的数据交换
- 13____java线程同步工具类之线程数据交换(Exchanger)
- exchanger 线程之间交换数据
- [笔记][Java7并发编程实战手册]3.8 并发任务间的数据交换Exchanger
- 14. 正则表达式和常见类 (Math、Random、System、BigInteger、BigDecimal、Date_DateFormat、Calendar)
- ajax请求的success方法与complete方法的区别
- 270. Closest Binary Search Tree Value
- 白帽子讲web安全(1)
- kafka简单配置测试
- 并发工具类(四)线程间的交换数据 Exchanger
- 正向代理与反向代理通俗版解释
- http Content-Type
- 短信验证
- 机器学习实战 树回归
- vtk实现两个相同的DICOM文件同步旋转
- 珠心算测验-vijos
- 遍历聚合对象中的元素——迭代器模式(三)
- BOM导致的空白问题