Java并发编程系列之二十四:Exchanger
2016-04-07 14:41
471 查看
Exchanger是一个线程间交换数据的工具类。
Exchanger从字面上可以理解为交换者,是一个可以用于线程间协作的工具类。主要用于线程间的数据交换。Exchanger提供一个同步点,在这个同步点上,两个线程可以交换彼此的数据。这两个线程可以通过exchange方法交换数据,当然存在线程执行不同步的情况,如果第一个线程先到达同步点,那么在第二个线程到达同步点之前,第一个线程会阻塞等待,直到两个线程都到达同步点,两个线程就可以使用exchange方法交换彼此的数据。
Exchanger可以用于遗传算法得到不同的交配结果。也可以用于校验数据,比如有两个会计师进行账目的对账工作,为了防止出错,系统可以将这两个会计师对账的结果进行比对,从而检查结果是否一致。下面的代码演示了这个场景:
代码执行的结果如下:
![](https://img-blog.csdn.net/20160407143933247)
程序中如果有一个线程没有到达同步点,则会一直等待,如果不希望一直等待可以使用指定等待时间的exchange(V x,long timeout,TimeUnit unit)指定最长的等待时间。
Exchanger从字面上可以理解为交换者,是一个可以用于线程间协作的工具类。主要用于线程间的数据交换。Exchanger提供一个同步点,在这个同步点上,两个线程可以交换彼此的数据。这两个线程可以通过exchange方法交换数据,当然存在线程执行不同步的情况,如果第一个线程先到达同步点,那么在第二个线程到达同步点之前,第一个线程会阻塞等待,直到两个线程都到达同步点,两个线程就可以使用exchange方法交换彼此的数据。
Exchanger可以用于遗传算法得到不同的交配结果。也可以用于校验数据,比如有两个会计师进行账目的对账工作,为了防止出错,系统可以将这两个会计师对账的结果进行比对,从而检查结果是否一致。下面的代码演示了这个场景:
package com.rhwayfun.patchwork.concurrency.r0407; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by rhwayfun on 16-4-7. */ public class ExchangerDemo { /** * 交换器 */ private static final Exchanger<String> exchanger = new Exchanger<>(); /** * 线程池 */ private static ExecutorService threadPool = Executors.newFixedThreadPool(2); /** * */ private static final DateFormat format = new SimpleDateFormat("HH:mm:ss"); /** * 主线程 * @param args */ public static void main(String[] args){ //第一个会计师进行对账 threadPool.execute(new Runnable() { @Override public void run() { try { String resA = "A's result"; //调用exchange方法表示当前线程已经到达了同步点 exchanger.exchange(resA); System.out.println(Thread.currentThread().getName() + " arrives at syncPoint at " + format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } }); //第二个会计师进行对账 threadPool.execute(new Runnable() { @Override public void run() { try { String resB = "B's result"; String resF = exchanger.exchange(resB); System.out.println(Thread.currentThread().getName() + " arrives at syncPoint at " + format.format(new Date())); System.out.println("Is the data consistent?" + resF.equals(resB) + ". A:" + resF + ", B:" + resB + " at " + format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } }); //关闭线程池 threadPool.shutdown(); } }
代码执行的结果如下:
程序中如果有一个线程没有到达同步点,则会一直等待,如果不希望一直等待可以使用指定等待时间的exchange(V x,long timeout,TimeUnit unit)指定最长的等待时间。
相关文章推荐
- Spring 注释(一) @Controller @Component @Repository @Service
- spring mybatis sqlSession WARN错误
- DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.
- JavaBean, EbtutyBean, POJO概念
- Java动态代理实现
- eclipse svn 插件安装
- DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.
- java JPA 介绍
- 【Bug解决日志】newUri.getPathSegments().get(1) 报错: java.lang.IndexOutOfBoundsException
- Java核心技术卷一 第11章 异常、断言和日志
- struts addFieldError()方法添加的数据怎么在页面显示
- foreach语句和传统的for循环语句区别
- Spring分布式事务实现
- Eclipse快捷键大全,导包快捷键:ctrl+Shift+/
- 超越线程池:Java并发并没有你想的那么糟糕
- 求数组中的最小子数组,时间复杂度o(n),java
- JDK源码分析:java.lang.Boolean
- [疯狂Java]SQL-DDL:索引、视图
- java Map集合类
- Java对象与Map的转换