如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到Exchanger这个类,Exchanger为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange ()方法并给出对象时,才能接受其他线程返回时给出的对象。
      
       Exchanger的构造方法如下:
[java] 
Exchanger();  //创建一个新的 Exchanger。

Exchanger用到的主要方法有:
[java]
exchange(V x);  //等待另一个线程到达此交换点(除非它被中断),然后将给定的对象传送给该线程,并接收该线程的对象。 
exchange(V x, long timeout, TimeUnit unit);   // 等待另一个线程到达此交换点(除非它被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。

下面是demo代码:

 package com.xt.thinks21_7;

 import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit; public class ThreadLocalTest { public static void main(String[] args) {
Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
new Thread1(exchanger).start();
new Thread2(exchanger).start();
} } class Thread1 extends Thread {
List<Integer> list = new ArrayList<Integer>();
Exchanger<List<Integer>> exchanger = null; public Thread1(Exchanger<List<Integer>> exchanger) {
this.exchanger = exchanger;
} @Override
public void run() {
Random rand = new Random();
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
System.out.println("\nThread1:list-->" + list.size() + "\n" + list);
for (int i = 0; i < 10; i++) {
try {
list = exchanger.exchange(list);
System.out.println("\nThread1:sizeoflist-->" + list.size()
+ "\n" + list);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} class Thread2 extends Thread {
List<Integer> list = new ArrayList<Integer>();
Exchanger<List<Integer>> exchanger = null; public Thread2(Exchanger<List<Integer>> exchanger) {
this.exchanger = exchanger;
} @Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Random rand = new Random();
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
System.out.println("\nThread2:list-->" + list.size() + "\n" + list);
for (int i = 0; i < 10; i++) {
try {
list = exchanger.exchange(list);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("\nThread2:sizeoflist-->" + list.size() + "\n"
+ list);
}
}
}

输出结果:

Thread1:list-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:list-->5

[2774, 3676, 2137, 1446, 9944]

Thread2:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread1:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread2:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread1:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread1:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread2:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread1:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread1:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread1:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread2:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread1:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread1:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread2:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread1:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

Thread1:sizeoflist-->5

[5943, 3873, 5422, 2297, 3070]

Thread2:sizeoflist-->5

[2774, 3676, 2137, 1446, 9944]

从输出结果中可以看出两个线程互相交换数据,直到循环结束。

JAVA之Exchanger的更多相关文章

  1. Java线程--Exchanger使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11868576.html Java线程--Exchanger使用: Exchanger 是用来交 ...

  2. java并发Exchanger的使用

    目录 简介 类定义 类继承 构造函数 两个主要方法 具体的例子 结语 简介 Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的.这里主要是两个线程之间交换持有的对 ...

  3. java多线程-Exchanger

    简介: 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给exchange方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象.Exchanger 可能被视为Synchr ...

  4. java多线程编码注意事项

    Sole purpose of using concurrency is to produce scalable and faster program. But always remember, sp ...

  5. dubbo开发者指南

    开发者指南 参与 流程 任务 版本管理 源码构建 框架设计 整体设计 模块分包 依赖关系 调用链 暴露服务时序 引用服务时序 领域模型 基本原则 扩展点加载 扩展点配置 扩展点自动包装 扩展点自动装配 ...

  6. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  7. 【Java并发编程实战】-----“J.U.C”:Exchanger

    前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...

  8. Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger

    前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...

  9. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

随机推荐

  1. DIR和dirent结构体

    DIR结构体类似于FILE,是一个内部结构 struct __dirstream { void *__fd; char *__data; int __entry_data; char *__ptr; ...

  2. not valid for Running the scheme

    The run destination iPhone6 Plus is not valid for Running the scheme 'MyApp’. Phone6 Plus's iOS 8.0 ...

  3. PHP获取毫秒时间戳

    我们知道,PHP中time()函数获取的时间戳,其单位是秒. 但是,前端JS获取的时间戳,单位是毫秒. 那么,在实际应用中,如何将JS和PHP的时间戳统一,即如何使用PHP获取毫秒时间戳呢,请看下例: ...

  4. php获取当前日期-7天

    // 将目前的时间戳值放入一数组内$strdate = '2014-02-03';$desDate = strtotime($strdate);//var_dump($desDate); $times ...

  5. block,inline,inline-block

    block元素的特点是: 总是在新行上开始: 高度,行高以及顶和底边距都可控制: 宽度缺省是它的容器的100%,除非设定一个宽度 <div>, <p>, <h1>, ...

  6. Android各层推荐开发书籍及参考资料

    Android各层推荐开发书籍及参考资料 转自:http://blog.csdn.net/fancylovejava/article/details/8657058 Android系统按照架构来说一共 ...

  7. 修改TOMCAT服务器图标为应用LOGO

    在tomcat下部署应用程序,运行后,发现在地址栏中会显示tomcat的小猫咪图标.有时候,我们自己不想显示这个图标,想换成自己定义的的图标,那么按如下方法操作即可: 参考网上的解决方案:1.将$TO ...

  8. poj3006---素数筛法

    #include <stdio.h> #include <stdlib.h> ];//以后都用宏定义 MAX int main()//如要将包括1000000在内的打表,数组就 ...

  9. aix6.1 openssh安装

    环境: IBM AIX6.1 1.下载(可以直接从附件中下载): openssl IBM官方网站下载:https://www14.software.ibm.com/webapp/iwm/web/reg ...

  10. Guava缓存器源码分析——缓存统计器

    Guava缓存器统计器实现: 全局统计器——         1.CacheBuilder的静态成员变量Supplier<StatsCounter> CACHE_STATS_COUNTER ...