并发编程系列之Exchanger

2023-11-03

前言

上面我们介绍了信号量,再来说说交换者,这个东西用的不是很多,所以一般也不被经常关注,但是我们还是最好了解下,下面我将从什么是Exchanger以及如何使用Exchanger两个方面谈谈这个用于线程间协调的工具类。

 

什么是Exchanger?

Exchanger主要是用于线程之间进行数据交换的,提供一个同步点,在这个同步点,两个线程可以交换彼此的数据;两个线程通过Exchanger方法来进行交换,当第一个线程先执行Exchanger()方法,他会一直等待第二个线程也执行Exchanger方法,然后两个线程交换数据。

举个通俗点的例子,就例如,你和你女朋友一起去逛超市,然后进入超市之后,你俩约好每个人去买各自需要的用品,然后约好在结算台那里见面,不管你俩谁先买好东西到达服务台,都需要把东西放在服务台然后等待对方,当你俩都到达结账台时,你俩互相交换各自买的东西,看看对方都买了些啥(当然如果你跟你女朋友真是这么逛街的,估计也处不长,扯远了点),然后结账,完事。这个过程就是Exchanger交换数据过程,而你俩分别就是那两个线程。

 

如何使用Exchanger?

首先我们需要一个创建一个交换者

Exchanger<String> exgr = new Exchanger<String>();

然后到达同步点,等待交换:

public V exchange(V x) throws InterruptedException {
       if (!Thread.interrupted()) {
           Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0);
           if (v == NULL_ITEM)
               return null;
           if (v != CANCEL)
               return (V)v;
           Thread.interrupted(); // Clear interrupt status on IE throw
       }
       throw new InterruptedException();
   }

 

下面我们来看示例,模拟你和女朋友逛超市:

public class ExchangerDemo {
   // 超市结账服务台(同步点)
   private static final Exchanger<String> exgr = new Exchanger<String>();
   // 你和你女朋友
   private static ExecutorService threadPool = Executors.newFixedThreadPool(2);
   public static void main(String[] args) {
       System.out.println("逛街开始,行动!!!");
       threadPool.execute(new Runnable() {
           @Override
           public void run() {
               System.out.println("你进入超市");
               try {
                   String u = "电子产品";
                   System.out.println("你购买ok,到达服务台");
                   // 到达同步点,等待或者交换(所有线程都到达)
                   exgr.exchange(u);
               } catch (InterruptedException e) {
               }
           }
       });

       threadPool.execute(new Runnable() {
           @Override
           public void run() {
               System.out.println("女朋友进入超市");
               try {
                   String girlfriend = "化妆品";
                   // 交换购买物品   到达同步点,等待或者交换(所有线程都到达)
                   String u1 = exgr.exchange("girlfriend");
                   System.out.println("女朋友到达服务台,交换购买物品");
                   System.out.println("你购买的是:"
                           + u1 + ",女朋友购买的是:" + girlfriend);
               } catch (InterruptedException e) {
               }
           }
       });
       threadPool.shutdown();
   }
}

执行结果:

当然还有一种情况,就是可能会你和你女朋友分开逛街的过程中,出现点状况,导致你买好东西之后,在服务台一直等她,她都没来(没来原因自己脑补),然后你也不能一直等下去啊,然后你就自己结账走人了,然后,然后,你就单身了...,对于这种情况,Exchanger提供了一个超时交换的方法,设置最大等待时间,源代码如下:

public V exchange(V x, long timeout, TimeUnit unit)
       throws InterruptedException, TimeoutException {
       if (!Thread.interrupted()) {
           Object v = doExchange((x == null) ? NULL_ITEM : x,
                                 true, unit.toNanos(timeout));
           if (v == NULL_ITEM)
               return null;
           if (v != CANCEL)
               return (V)v;
           if (!Thread.interrupted())
               throw new TimeoutException();
       }
       throw new InterruptedException();
   }

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并发编程系列之Exchanger 的相关文章

  • MPI测试程序

    include
  • 单例模式的4种写法

    单例模式是开发过程中常用的模式之一 首先了解下单例模式的四大原则 构造方法私有 以静态方法或枚举返回实例 确保实例只有一个 尤其是多线程环境 确保反射或反序列化时不会重新构建对象 饿汉模式 饿汉模式在类被初始化时就创建对象 以空间换时间 故
  • 一次线上的GC问题排查

    6 19号下午 线上系统出现了一次实时链路数据 不通畅的问题 业务方反应更新的增量数据没有流入到HA3搜索集群 登录机器后检查日志后发现 在周六晚上到周天下午 cr search merge 机器人schema统一 表增量数据猛增 初步估计
  • JUC三连问

    1 进程和线程的区别 1 进程是资源分配的基本单位 线程是程序执行的最小单位 2 一个进程包括多个线程 3 每个进程都有自己的内存和资源 一个进程中的线程会共享这些内存和资源 每个线程都有单独的栈内存 和寄存器 2 并行和并发的区别 并行指
  • 场景题之最快返回结果

    场景题之最快返回结果 问题描述 输入中文 最快从百度翻译 谷歌翻译 有道翻译获取结果返回 代码实现 思路 采用CompletableFuture实现 多个CompletableFuture可以串行执行 也可以并行执行 其中anyOf 方法只
  • JUC常用到的类

    JUC java util concurrent 并发包中包含了许多并发编程中需要用到的类 锁 如ReentratLock ReadWriteLock ReentrantLock重入锁 可以替代synchronized使用 并且有更多强大的
  • MPI与main()程序中的其他函数执行次数

    我原先以为只有在MPI代码区域 即MPI Init argc argv 到MPI Finalize 中的代码才会涉及到进程通信的问题 但实际上在MPI区域外的代码依然受到影响 执行的次数与开启的进程数有关 为此可以使用MPI 秩 rank
  • 如何设计高性能的分布式锁

    什么是分布式锁 在 JVM 中 在多线程并发的情况下 我们可以使用同步锁或 Lock 锁 保证在同一时间内 只能有一个线程修改共享变量或执行代码块 但现在我们的服务都是基于分布式集群来实现部署的 对于一些共享资源 在分布式环境下使用 Jav
  • Java并发编程-第二章

    以下内容来自 Java并发编程 书籍第二章 补充 1 volatile的有序性 volatile通过内存屏障实现禁止指令重排序保证有序性 硬件层面的内存屏障分为Load Barrier 和 Store Barrier即读屏障和写屏障 2 同
  • 从0实现基于Linux socket聊天室-实现聊天室的公聊、私聊功能-4

    前面文章链接如下 从0实现基于Linux socket聊天室 多线程服务器模型 1 从0实现基于Linux socket聊天室 多线程服务器一个很隐晦的错误 2 从0实现基于Linux socket聊天室 实现聊天室的登录 注册功能 3 上
  • CUDA编程问题记录:能否用CPU多线程调用CUDA核函数

    问题 能否在主机端创建CPU多线程 在每个线程里调用设备端核函数的caller函数 进而实现进一步的并行运行 例如有5张图片 对于每张图片都有N个GPU线程对其进行像素操作 但是此时是逐一对这5张图片处理的 想在主机端创建5个CPU线程 每
  • 线程的状态与切换

    Java中的线程的生命周期大体可分为5种状态 1 新建 初始化 NEW 新创建了一个线程对象 2 可运行 RUNNABLE 线程对象创建后 其他线程 比如main线程 调用了该对象的start 方法 该状态的线程位于可运行线程池中 等待被线
  • ThreadPoolExecutor源码解析

    ThreadPoolExecutor源码解析 一 新建线程池的是构造方法 public ThreadPoolExecutor int corePoolSize int maximumPoolSize long keepAliveTime T
  • 并发编程系列之CountDownLatch对战Cyclicbarrier

    前言 前面我们介绍了并发容器和队列 今天我们来介绍几个非常有用的并发工具类 今天主要讲CountDownLatch和Cyclicbarrier这两个工具类 通过讲解并对比两个类的区别 OK 让我们开始今天的并发之旅吧 什么是CountDow
  • 深入理解synchronized底层原理,一篇文章就够了!

    文章目录 前言 一 synchronized的特性 1 1 原子性 1 2 可见性 1 3 有序性 1 4 可重入性 二 synchronized的用法 三 synchronized锁的实现 3 1 同步方法 3 2 同步代码块 四 syn
  • 进程、线程、管程、纤程、协程概念以及区别

    进程 进程是指在操作系统中能独立运行并作为资源分配的基本单位 由一组机器指令 数据和堆栈等组成的能独立运行的活动实体 进程在运行是需要一定的资源 如CPU 存储空间和I O设备等 进程是资源分配的基本单位 进程的调度涉及到的内容比较多 存储
  • 锁介绍名词解释&&Lock && synchronized

    各种锁名词解释及应用 一 名词解释 1 乐观锁 VS 悲观锁 2 自旋锁 VS 适应性自旋锁 3 无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁 4 公平锁 VS 非公平锁 5 可重入锁 VS 非可重入锁 6 独享锁 VS 共享锁 二
  • 死锁产生条件和解决办法

    死锁 死锁产生的四个条件 产生死锁必须同时满足以下四个条件 只要其中任一条件不成立 死锁就不会发生 互斥条件 线程要求对所分配的资源 如打印机 进行排他性控制 即在一段时间内某资源仅为一个线程所占有 此时若有其他线程请求该资源 则请求线程只
  • brpc源码解析(十七)—— bthread上的类futex同步组件butex详解

    文章目录 一 futex简介 二 butex源码解析 2 1 butex相关数据结构 2 2 butex主要机制 2 2 1 butex wait 2 2 2 butex wake 我们知道在linux 下 锁和其他一些同步机制都会用到fu
  • 接口并发性能测试开发之:从测试方案设计、测试策略、指标分析到代码编写,这一篇全搞定。

    并发接口性能设计思路与代码编写 1 引言 2 并发测试定义 3 并发测试分类 4 设计思路整理 5 测试方案设计 6 指标分析 7 代码实战 8 总结 1 引言 这篇是我3月份在公司内部做的技术分享内容 由于我在公司内部分享的内容较多 以及

随机推荐

  • 复习:详解函数重载

    什么是函数重载 一组函数 处于同一个作用域 其中函数名相同 参数列表的个数或类型不同 那么这一组函数就成为函数重载 一组函数要称得上函数重载 一定是处在同一个作用域中函数名同 参数列表同 返回值不同 不叫重载 因为函数符号都相同函数重载是通
  • sprintf与snprintf区别

    sprintf的原型如下 int sprintf char str const char format sprintf是字符串格式化命令 主要功能是把格式化的数据写入字符串str中 返回值为写入str的字节数 结束字符 0 不计入内 其中
  • 用户交易数据分析 - 投资绩效归因分析-Brision模型

    1 模型介绍 通过业绩归因 能够更加清楚组合的收益究竟来源于什么 进而知道这种获取超额收益的能力是否能够持续 也能够明白组合发生剧烈波动的原因 从而改进策略 Brision模型中 将组合的收益分四部分 选股收益 在资产类别 或板块 内部 超
  • spring boot 之JPA详解

    JPA参考文档 JPA详解 jpa之分页 本地sql查询 注意表名啥的都用数据库中的名称 适用于特定数据库的查询 public interface UserRepository extends JpaRepository
  • Qt 槽机制:public slots 和 private slots

    今天在写Qt图片浏览器的时候 遇到了一个问题 Qt的界面是对的 但是功能却怎么也实现不了 点击开始按钮 无法显示打开文件夹的对话框 开始以为是信号连接或者是函数写错了 检查了好久都不知道问题在哪 最后 对着书上的代码一行行研究 才发现问题在
  • k8s第二节 Kubernetes入门、安装、创建Deployment、Service、pod调度 污点taint

    一 k8s的集群架构与组件 k8s也是一个Master 多个node节点 下面是kubernetes结婚的架构与组件 1 1 master组件介绍 组件名称 介绍 kube apiserver Kubernetes API 集群的统一入口
  • cgo+gSoap+onvif学习总结:2、wsl编译安装gSoap

    cgo gSoap onvif学习总结 2 wsl编译安装gSoap 文章目录 cgo gSoap onvif学习总结 2 wsl编译安装gSoap 1 前言 2 gSoap编译安装 wsl环境编译安装 3 最后 1 前言 结合官网安装教程
  • 用VB制作一个AI聊天机器人(001)

    从现在开始 我们要用VB做一款聊天机器人 材料 VB6 0 准备 拉出2个text控件 一个command控件 代码可以这样写 仅供参考 Private Sub Command1 Click If InStr LCase Text1 Tex
  • 简单聊一聊磁珠,电感和0R电阻

    磁珠 磁珠的材料是铁镁或铁镍合金 一般这些材料具有有很高的电阻率和磁导率 在高频率和高阻抗下 电感内线圈之间的电容值会最小 磁珠通常只适用于高频电路 因为在低频时 它们基本上是保有电感的完整特性 包含有电阻性和电抗性分量 因此会造成线路上的
  • 腾讯云16核服务器配置大全_16核CPU型号性能测评

    腾讯云16核CPU服务器有哪些配置可以选择 可以选择标准型S6 标准型SA3 计算型C6或标准型S5等 目前标准型S5云服务器有优惠活动 性价比高 计算型C6云服务器16核性能更高 轻量16核32G28M带宽优惠价3468元15个月 腾讯云
  • 在Vim中配置C++环境和插件

    介绍 本文章讲述了如何用coc nvim来安装coc clang插件 和如何安装前置要求 clangd npm nodejs 并配置 vimrc文件和clangd路径来让vim可以autofill cpp 目录 介绍 1 配置 vimrc
  • nc命令介绍

    一 简介 nc是netcat的简写 被用作一个简单 可靠的网络工具 二 作用 实现任意TCP UDP端口的侦听 nc可以作为server以TCP或UDP方式侦听指定端口 端口的扫描 nc可以作为client发起TCP或UDP连接 机器之间传
  • C++ Char操作

    C Char操作 1 字符处理函数 isalpha ch 如果ch是一个字母 返回非 int 0值 否则 返回 int 0 isalnum 判断是否是字母或者数字字符 isdigit 判断是否是数字字符 0 9 islower 判断是否是小
  • CentOS 查看系统版本和位数

    查看系统版本 方法一 cat etc redhat release 方法二 cat proc version 方法三 uname a 查看系统位数 64 or 32 方法一 getconf LONG BIT 方法二 file bin ls
  • Windows——Active Directory域服务安装与测试

    实验原理 在Windows server 2008 上安装域并创建域用户 将Win7加入到该域中 然后用域账户登录以及用Win7本地账户登录Win7 实验环境 Windows server 2008 域控制器 Win7 加入域的PC 在开始
  • Java线程:新特征-障碍器

    本文转载至 http lavasoft blog 51cto com 62575 222738 Java5中 添加了障碍器类 为了适应一种新的设计需求 比如一个大型的任务 常常需要分配好多子任务去执行 只有当所有子任务都执行完成时候 才能执
  • 多线程面试题摘选

    多线程面试题摘选 一 概念性问答题 1 线程的基本概念 线程的基本状态及状态之间的关系 答 线程是指在程序执行过程中 能够执行程序代码的一个执行单位 每个程序至少都有一个线程 也就是程序本身 java线程的基本状态 运行 就绪 挂起 结束
  • 无人机轨迹学习问题

    无人机轨迹学习 路径跟踪方案 个人总结 1 强化学习 建立一种奖励机制 它最符合人类的学习机制 学习一个最优策略 policy 可以让本体 agent 在特定环境 environment 中 根据当前的状态 state 做出行动 actio
  • ctf.show web2

    单引号无回显也无报错 or 1 1 有回显 order by测试也没特殊回显好像必须要带入sql函数才能回显 直接进行union select 1 查看当前数据库名称 1 or 1 1 union select 1 database 3 l
  • 并发编程系列之Exchanger

    前言 上面我们介绍了信号量 再来说说交换者 这个东西用的不是很多 所以一般也不被经常关注 但是我们还是最好了解下 下面我将从什么是Exchanger以及如何使用Exchanger两个方面谈谈这个用于线程间协调的工具类 什么是Exchange