Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交换数据。因此该工具类的线程对象是成对的。

Exchanger类提供了两个方法,String exchange(V x):用于交换,启动交换并等待另一个线程调用exchange;String exchange(V x,long timeout,TimeUnit unit):用于交换,启动交换并等待另一个线程调用exchange,并且设置最大等待时间,当等待时间超过timeout便停止等待。

实例讲解

package concurrent;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.*;
public class ExchangerDemo {

public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();

final Exchanger exchanger = new Exchanger();
executor.execute(new Runnable() {
String data1 = "克拉克森,小拉里南斯";

@Override
public void run() {
nbaTrade(data1, exchanger);
}
});

executor.execute(new Runnable() {
String data1 = "格里芬";

@Override
public void run() {
nbaTrade(data1, exchanger);
}
});

executor.execute(new Runnable() {
String data1 = "哈里斯";

@Override
public void run() {
nbaTrade(data1, exchanger);
}
});

executor.execute(new Runnable() {
String data1 = "以赛亚托马斯,弗莱";

@Override
public void run() {
nbaTrade(data1, exchanger);
}
});

executor.shutdown();
}

private static void nbaTrade(String data1, Exchanger exchanger) {
try {
System.out.println(Thread.currentThread().getName() + "在交易截止之前把 " + data1 + " 交易出去");
Thread.sleep((long) (Math.random() * 1000));

String data2 = (String) exchanger.exchange(data1);
System.out.println(Thread.currentThread().getName() + "交易得到" + data2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

运行程序,得到如下结果:

pool-1-thread-1在交易截止之前把 克拉克森,小拉里南斯 交易出去
pool-1-thread-2在交易截止之前把 格里芬 交易出去
pool-1-thread-3在交易截止之前把 哈里斯 交易出去
pool-1-thread-4在交易截止之前把 以赛亚托马斯,弗莱 交易出去
pool-1-thread-2交易得到哈里斯
pool-1-thread-3交易得到格里芬
pool-1-thread-4交易得到克拉克森,小拉里南斯
pool-1-thread-1交易得到以赛亚托马斯,弗莱

Exchanger 原理的更多相关文章

  1. 同步工具——Exchanger

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 本文是转载文章,原文请见这里 一.Exchanger简介 ...

  2. Java面试通关要点汇总集

    Java面试通关要点汇总集 2018-03-09 转自:Java面试通关要点汇总集 文章目录 1. 基础篇  1.1. 基本功  1.2. 集合  1.3. 线程  1.4. 锁机制2. 核心篇  2 ...

  3. Java面试题[转载]

    目录 转载 简历篇 请自我介绍 请介绍项目 基础篇 基本功 面向对象的特征 final, finally, finalize 的区别 int 和 Integer 有什么区别 重载和重写的区别 抽象类和 ...

  4. Java基础知识盘点(三)- 线程篇

    创建线程的方式及实现 一.继承Thread类创建线程类 1.定义Thread的子类,并重写run方法,因为该方法的方法体就是代表了线程要完成的任务,因此run方法又叫做执行体. 2.创建Thread子 ...

  5. Java面试问题汇总

    转一些面试经验 刚看到下面这份面试清单,从个人的开发面试经历看,里面总结的大部分内容还是很不错的.年后想跳槽的朋友可以选取里面的问题准备一下. GitHub上的面试总结帖 Interview-Note ...

  6. java面试一、1.3线程与进程

    免责声明:     本文内容多来自网络文章,转载为个人收藏,分享知识,如有侵权,请联系博主进行删除. 1.3.进程和线程 线程和进程的概念.并行和并发的概念 线程和进程: 线程:是程序执行流的最小单元 ...

  7. Java面试通关秘籍汇总集

    一.基础篇 1.1.Java基础 面向对象的特征:继承.封装和多态 final, finally, finalize 的区别 Exception.Error.运行时异常与一般异常有何异同 请写出5种常 ...

  8. 最新Java面试题及答案整理

    基础篇 一.基本功 面向对象特征 封装,继承,多态和抽象 1. 封装 封装给对象提供了隐藏内部特性和行为的能力.对象提供一些能被其他对象访问的方法来改变它内部的数据.在 Java 当中,有 3 种修饰 ...

  9. 从1.6W名面试者中收集的Java面试题精选汇总(内附知识脑图)

      本篇的面试题是接之前读者的要求,发出来的. 首先,声明下,以下知识点并非全部来自BAT的面试题. 如果觉得在本文中笔者总结的内容能对你有所帮助,可以点赞关注一下. 本文会以引出问题为主,后面有时间 ...

随机推荐

  1. Django创建数据库常用字段及参数

    Django创建数据库常用字段及参数 常用字段 1.models.AutoField 自增列= int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列 ...

  2. CVE-2018-20169漏洞学习

    简介 在4.19.9之前的Linux内核中发现了一个问题.USB子系统在读取与驱动程序/ USB /core/usb.c中的_usb_get_extra_descriptor相关的额外描述符时错误地检 ...

  3. Arkady and a Nobody-men CodeForces - 860E (虚树)

    大意: 给定有根树, 根节点深度为$1$. 定义$r(a,b)$为$b$子树内深度不超过$a$的节点数$-1$ 定义$z_a$为$a$的所有祖先的$r$之和. 对于所有点求出$z$的值. 一个点$y$ ...

  4. 【Tomcat】热部署的遗留配置导致服务器无法启动

    1.问题描述: 今天用myeclipse写了个小demo,然后用Tomcat7 部署了,接着点击启动服务器,服务器居然报错: 严重: Error starting static Resources j ...

  5. luogu题解 P1099 【树网的核】树的直径变式+数据结构维护

    题目链接: https://www.luogu.org/problemnew/show/P1099 https://www.lydsy.com/JudgeOnline/problem.php?id=1 ...

  6. pgsql sql字段拼接

    1.  一条记录数据字段拼接 语法:concat_ws('拼接符号',字段名,more fields) 例子:concat_ws(':',username,sex)2. 多条记录字段拼接 语法:con ...

  7. TensorFlow入门——hello

    上一节说了TensorFlow的安装,这一节说一下测试的问题 新建一个Python文件,输入 import tensorflow as tf hello = tf .constant (’Hello, ...

  8. springboot启动端口占用问题,报错org.apache.catalina.LifecycleException: Protocol handler start failed

    解决办法,找到被占用的端口

  9. Navicat连接Mysql11.1.13出现1251错误

    打开Navicat软件,单击左上角[连接]按钮,选择mysql,弹出新建连接,输入相关信息,单击[连接测试],报1251的错误,如下图所示: 根因分析: mysql8 之前的版本中加密规则是mysql ...

  10. linux版宝塔安装Redis

    1安装服务 2配置设置 3安装PHP扩展 首先,我们来安装服务,进入管理面板--软件管理--运行环境--redis-点击安装,等待完成 完成之后开始第二步,配置设置.这一步根据自己需要进行配置.注意安 ...