在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中

在生产者-消费者情境模式中它包含了一个数缓冲区,一个或者多个生产者,一个或者多个消费中

下面是生产者和消费者的示例:

/**
* 生产者和消费者交换数据
*/
public class MyExchanger {
public static void main(String[] args) {
Exchanger<List<String>> exchanger = new Exchanger<List<String>>(); Producer1 producer = new Producer1(new ArrayList<String>(), exchanger);
Consumer1 consumer = new Consumer1(new ArrayList<String>(), exchanger); new Thread(producer).start();
new Thread(consumer).start();
}
} /** 生产者线程*/
class Producer1 implements Runnable{ /**
* 存储交换的数据
*/
private List<String> buffer; /**
* 和消费者要交换的对象
*/
private final Exchanger<List<String>> exchanger; Producer1(List<String> buffer,Exchanger<List<String>> exchanger){
this.buffer = buffer;
this.exchanger = exchanger;
} @Override
public void run() {
for(int i = 0 ; i < 2 ; i++){
String message = "" + i ;
System.out.println("Produce的数据 : " + message);
buffer.add(message); //调用exchange()与消费者进行数据交换
try {
buffer = exchanger.exchange(buffer);
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println("Produce收到来自Consumer的数据的长度 : " + buffer.size());
}
} /** 消费者线程*/
class Consumer1 implements Runnable{
private List<String> buffer; private final Exchanger<List<String>> exchanger; public Consumer1(List<String> buffer,Exchanger<List<String>> exchanger){
this.buffer = buffer;
this.exchanger = exchanger;
} @Override
public void run() {
for(int i = 0 ; i < 2 ; i++){
//调用exchange()与消费者进行数据交换
try {
buffer = exchanger.exchange(buffer);
} catch (InterruptedException e) {
e.printStackTrace();
} for(int j = 0 ; j < buffer.size() ; j++){
System.out.println("Consumer收到来自Produce的数据 : " + buffer.get(0));
buffer.remove(0);
}
} System.out.println("Consumer清空数据");
}
}

控制台输出:

Produce的数据 : 0
Consumer收到来自Produce的数据 : 0
Produce的数据 : 1
Produce收到来自Consumer的数据的长度 : 0
Consumer收到来自Produce的数据 : 1
Consumer清空数据

在Exchanger中,如果一个线程已经到达了exchanger节点时,对于它的伙伴节点的情况有三种:

1、如果它的伙伴节点在该线程到达之间已经调用了exchanger方法,则它会唤醒它的伙伴然后进行数据交换,得到各自数据返回。

2、如果它的伙伴节点还没有到达交换点,则该线程将会被挂起,等待它的伙伴节点到达被唤醒,完成数据交换。

3、如果当前线程被中断了则抛出异常,或者等待超时了,则抛出超时异常

Java并发编程--6.Exchanger线程间交换数据的更多相关文章

  1. Java并发编程(04):线程间通信,等待/通知机制

    本文源码:GitHub·点这里 || GitEE·点这里 一.概念简介 1.线程通信 在操作系统中,线程是个独立的个体,但是在线程执行过程中,如果处理同一个业务逻辑,可能会产生资源争抢,导致并发问题, ...

  2. JAVA 并发编程-多个线程之间共享数据

    原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...

  3. JAVA 并发编程-多个线程之间共享数据(六)

    多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...

  4. 【转】JAVA 并发编程-多个线程之间共享数据

    原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...

  5. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  6. Java并发工具类(四):线程间交换数据的Exchanger

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

  7. Java并发工具类之线程间数据交换工具Exchanger

    Exchanger是一个用于线程间协做的工具类,主要用于线程间的数据交换.它提供了一个同步点,在这个同步点,两个线程可以彼此交换数据.两个线程通过exchange方法交换数据,如果一个线程执行exch ...

  8. Java并发编程扩展(线程通信、线程池)

    之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...

  9. 【java并发编程实战】-----线程基本概念

    学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...

随机推荐

  1. php-fpm.conf 重要参数 max_children 和 request_terminate_timeout

    php-fpm.conf 重要参数 max_children 和 request_terminate_timeout php-fpm.conf有两个至关重要的参数:一个是”max_children”, ...

  2. Leet Palindrome Partitioning II

    class Solution { public: int minCut(string s) { int len = s.length(); ]; char* s_dp = new char[len * ...

  3. java集合(List集合与Map集合的数据转换)

    List集合与Map集合的数据转换 实现List和Map数据的转换. 具体要求如下: 功能1:定义方法public void listToMap( ){ }将List中Student元素封装到Map中 ...

  4. 在GDI+中如何实现以左下角为原点的笛卡尔坐标系

    今天写了一个求点集合的凸包的一个算法,虽然结果求解出来了,但是想将过程用GDI+绘制出来,就需要将点绘制出来,然而c#GDI+中绘图的坐标与我们常用数学中笛卡尔坐标系是不一样的,所以就要转换GDI+中 ...

  5. vmware参数详解

    config.ini - 设置 VMX文件参数 文件configs.ini或config(在Linux中)为所有用户设置参数,或者如果您喜欢 - 为主机设置参数. 如果要为所创建的所有虚拟机使用某些设 ...

  6. Flutter完整开发实战详解

    Flutter完整开发实战详解(一.Dart语言和Flutter基础) Flutter完整开发实战详解(二. 快速开发实战篇) Flutter完整开发实战详解(三. 打包与填坑篇)

  7. qemu模拟vexpress-a9及u-boot引导 linux

    前言 本文讲述使用 qemu 来模拟 vexpress-a9 开发板 ,同时介绍使用 u-boot 引导 linux 的流程.整个坐下来对 qemu 和 u-boot 以及嵌入式 linux 的工作方 ...

  8. 如何使用 adb 命令实现自动化测试

    如何使用 adb 命令实现自动化测试 一.前提: 1.打开手机调试模式,确保手机已正常连接电脑,可在电脑上通过adb devices命令查看,结果如下说明连接成功: List of devices a ...

  9. 八、Vue中的computed属性

    看了网上很多资料,对vue的computed讲解自己看的都不是很清晰,今天忙里抽闲,和同事们又闲聊起来,对computed这个属性才有了一个稍微比较清晰的认识,下面的文章有一部分是转自: https: ...

  10. canvas动画部分

    requestAnimationFrame(callback) 一个用于制作逐帧动画的函数 //这个函数会在控制台无限输出"----" (function animate() { ...