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. AcWing池塘计数

    这个题让我们求连通块得数数量,我考虑用flood fill算法. 也就是枚举这个地图每一个点,假如符合要求就bfs与这个点联通的点,并打上标记.结束后接着枚举没有被标记并且符号要求的点... 1.== ...

  2. 【NOIP2017】跳房子

    这题我0分. 比赛时,我一眼出正解,哈哈,太水了! 这题不就是一个二分+DP+单调队列吗? 然而,细节决定成败. 我错了许多细节,就挂了. 我只考了0分... 首先,这题满足一个条件: 保证g变大后, ...

  3. git diff 命令介绍

    https://www.jianshu.com/p/6e1f7198e76a https://www.jianshu.com/p/5b6a014ac3db https://blog.csdn.net/ ...

  4. Python进阶编程 类与类的关系

    类与类的关系 依赖关系 # 依赖关系: 将一个类的类名或者对象传给另一个类的方法中. class Elephant: def __init__(self, name): self.name = nam ...

  5. Makoto and a Blackboard CodeForces - 1097D (积性函数dp)

    大意: 初始一个数字$n$, 每次操作随机变为$n$的一个因子, 求$k$次操作后的期望值. 设$n$经过$k$次操作后期望为$f_k(n)$. 就有$f_0(n)=n$, $f_k(n)=\frac ...

  6. luogu题解 P1707 【刷题比赛】矩阵加速递推

    题目链接: https://www.luogu.org/problemnew/show/P1707 分析: 洛谷的一道原创题,对于练习矩阵加速递推非常不错. 首先我们看一下递推式: \(a[k+2]= ...

  7. Vue 路由拦截(对某些页面需要登陆才能访问)

    前言 做项目的时候有个需求,就是发现没有登录,竟然也可以进入我的主页,这样肯定是不能容忍的.于是就要让他进入主页的时候,加个判断是否有登录,若没有登录,则返回登录界面,登录成功后还可以跳转到之前进入的 ...

  8. 帝国cms 通过文章的id获取信息

    获取栏目id为13下id为46的数据 [e:loop={"select * from phome_ecms_news where classid = 13 and id = 46" ...

  9. springboot 集成 swagger 自动生成API文档

    Swagger是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的Web服务.简单来说,Swagger是一个功能强大的接口管理工具,并且提供了多种编程语言的前后端分离解决方案. S ...

  10. 织梦多个栏目arclist调用副栏目不显示的解决办法

    织梦arclist调用副栏目不显示,网上关于这个问题的解决办法有很多,其中一种是: 打开/include/taglib/arclist.lib.php,代码约位于295-296行(我目前用的DedeC ...