excelexportentity中设置null不显示的方法_一般人不知道的线程间数据交换Exchanger

线程间的数据共享除了定义一个共享数据然后各个线程去访问这种方式外,还可以使用Exchanger交换数据。

简单案例

首先看看Exchanger的运用,Exchanger最简单的测试代码,如下图:

4f5f846c7c8c9168d7c9461f77aa5910.png

对应打印的结果如下:

线程2创建对象java.lang.Object@3f6d4362

线程1创建对象java.lang.Object@c986ad7

线程2得到的类java.lang.Object@c986ad7

线程1得到的类java.lang.Object@3f6d4362

可以看出来线程2创建的对象与线程1得到的线程是同一个对象,也就是他们指向的是同一个引用。

Exchanger源码分析

Exchanger只提供了两个exchange方法,一个是只带交换的数据参数,另外一个不仅有数据参数,还有时间限制,这也从侧面说明exchange是一个阻塞线程的方法,并且可以指定阻塞时间,这里我们先分析下不带时间参数的exchange方法,源码分析主流程如下图:

3c472d4662c28a7538e6e3d1217540cb.png

左边是exchange方法的代码流程图,比较简单可以明显的看出来主要依靠两个方法slotExchange与arenaExchange方法,流程主要有两步,首先尝试从slotExchange方法获取值,如果获取为null则再从arenaExchange方法获取,当返回还是null时则抛出中断异常,否则最终返回结果

slotExchange源码分析

上图中右边的分析图是slotExchange方法的主要代码图,再分析这个方法前先说明一下Exchanger的一个内部类Node,Node有7个属性,这里先说明三个属性item(创建node线程要交换出去的值)、match(创建node线程要获取的值)、parked(创建node的线程);每个线程再执行到Exchanger方法后都会创建一个Node。

理解这个基本概念后,再来快速过一下slotExchange方法流程,方法包含两个循环,第一个循环分析如下:

首先判断Exchanger的slot是否为null,如果不为空则尝试修改slot值为null,如果修改成功则返回slot的item,并设置slot的match,并唤醒slot的线程,交换成功。如果设置失败则说明有其他线程正在修改slot,即存在竞争,这是会判断机器的CPU数,如果大于1则会初始化Exchanger的Node[] arena(这个是下个方法说明),进入下一个循环。

如果slot为null则判断arena是否为null,如果不为null则直接返回null,表示由arenaExchange去执行。

如果都不是则尝试当前线程的node的item设置为要交换的值,同时尝试设置为slot,设置成功则跳出循环,失败则进入下次循环;

第一个循环主要包含两步,如果slot不为null则尝试交换值,交换成功就返回,否则就尝试设置slot的值,设置成功就跳出循环;在cpu是多个的情况下又存在竞争的情况下会再arenaExchange去处理。

这个循环如果跳出来了则说明设置slot成功,那么当前线程只需要等待node的match不为null就行,所以第二个循环的判断条件就是node的match不为null,如果为null就挂起,当唤醒的时候再判断,直到node的match不为null则返回match的值。

分析arenaExchange方法

在slotExchange方法中会在存在竞争修改slot并且运行程序的机器的CPU大于1时会初始化Node[] arena属性,在第二次修改slot还存在竞争失败时就会返回null,这个时候就到了arenaExchange方法上场了。

arenaExchange也是一个for的无限循环,每次取出当前线程的Node来获取进行处理,这里再介绍node一个属性index,用来标记nodearena数组的位置,处理流程的简单分析如下:

首先根据node的index获取j(计算方法:index<<7+ABASE(1<<7的常量),原因后面特别说明),如果不为null则尝试修改arena的第j项为null,如果成功则返回arena[j]的node的item的值,并设置match,最后唤醒node保存的线程。

第二步如果node为null则把当前线程的node的item设置为要交换出去的值,然后尝试修改arena[j]的值为当前线程的node,如果修改成功则循环判断match的值,当不为null则返回值,否则判断线程中断等条件后则挂起线程,等唤醒再判断。

第三步也就是node不为null,但是在第一步更新失败后,会根据node的bound与Exchange的bound等对比,计算index的值,有时会增长有时会减少,然后进入下一个循环判断。

总结这三步主要目的如下,首先是尝试从arena找一个节点来交换数据,如果交换成功则唤醒对应的线程并返回交换结果,如果交换失败则更新index,再次尝试寻找并交换,如果在找到的arena[j]为null则尝试新建一个node并保存进arena,挂起线程等待唤醒

对之前的arena的j特别说明,把index扩大再作为数组的索引,原因是内存在加载数组一个元素时会把附近的也加载,而修改过后会把加载出来的设置为过期,为了避免这种浪费在数组间隔一定位置在设置值。

总结

Exchanger利用一个Node类型的属性slot实现线程间的交换,如果slot为null则初始化一个并设置item为需要交换的值,然后挂起,当其他线程进来的时候看到slot为null则取出node的item值,然后把自己要交换的值设置进match上,然后唤醒node中线程。

利用一个属性也够了,但是在并发的情况下吞吐量并不高,所以又建了一个Node的数组arena,线程在arena一个个找不为null的值,尝试修改直到修改成功,则获取node的item,再设置match并唤醒线程。如果找到的为null则自己主动new一个node并设置item,然后挂起等待唤醒。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

08d68d556716464ce4cbe319907f0111.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

布尔表达式的语法及语义分析程序_XSS语义分析的阶段性总结(一)

作者&#xff1a;Kale 合天智汇前言由于X3Scan的研发已经有些进展了&#xff0c;所以对这一阶段的工作做一下总结&#xff01;对于X3Scan的定位&#xff0c;我更加倾向于主动被动的结合。主动的方面主要体现在可以主动抓取页面链接并发起请求&#xff0c;并且后期可能参考XSStr…

【黑金原创教程】【TimeQuest】【第二章】TimeQuest模型角色,网表概念,时序报告...

声明&#xff1a;本文为黑金动力社区&#xff08;http://www.heijin.org&#xff09;原创教程&#xff0c;如需转载请注明出处&#xff0c;谢谢&#xff01; 黑金动力社区2013年原创教程连载计划&#xff1a; http://www.cnblogs.com/alinx/p/3362790.html 《FPGA那些事儿--Tim…

设置springboot日志级别_Spring Boot 日志框架实践

概述Java应用中&#xff0c;日志一般分为以下5个级别&#xff1a;ERROR 错误信息WARN 警告信息INFO 一般信息DEBUG 调试信息TRACE 跟踪信息Spring Boot使用Apache的Commons Logging作为内部的日志框架&#xff0c;其仅仅是一个日志接口&#xff0c;在实际应用中需要为该接口来指…

计算机加分乘法套用,8+8+8+8+8写成乘法算式要怎样写?小学数学为何这么死板?...

88888写成乘法算式只能写8x5不能写5x8吗&#xff1f;小学数学为何这么死板&#xff1f;这个题目来自于某小学的期考试卷&#xff0c;是个填空题&#xff0c;88888写成乘法算式时给了两个空( )和( )&#xff0c;就有人提出来只能写8x5不能写5x8&#xff0c;所以应该只给一个空。…

投影元素直接隔离_摸着夜色上露台开投影,是巴塞罗那设计师的浪漫

总有人说&#xff0c;世界为你关上一扇门&#xff0c;定会为你留有一扇窗。在家闷上个把月&#xff0c;窗户直接担起了连接人们与外界的通道。既然观众出不了门&#xff0c;那不如让加油打气的海报们&#xff0c;自己爬上墙好了——人们打开窗子就能撞上。平面设计师Ral Goi一直…

Apache Lucene的结构

不可估量的高贵的Apache软件基金会&#xff08;Apache Software Foundation&#xff09;产生了许多重要产品&#xff08;Ant&#xff0c;CouchDB&#xff0c;Hadoop&#xff0c;JMeter&#xff0c;Maven&#xff0c;OpenOffice&#xff0c;Subversion等&#xff09;&#xff0c…

comcerter无法识别串口_基于FPGA 的MXN维字符识别的实现

基于FPGA 的MXN维字符识别的实现1 概述本文的灵感来源于杨淑英老师的一张PPT&#xff08;手写数字识别&#xff09;&#xff0c;在此特别鸣谢杨淑英老师。一般机器视觉对事物是没有感知的&#xff0c;比如摄像头采集到一张苹果的图片&#xff0c;它本身是不知道那是什么东西&am…

构造函数必须没有代码

构造函数中应完成多少工作&#xff1f; 在构造函数内部进行一些计算然后封装结果似乎是合理的。 这样&#xff0c;当对象方法需要结果时&#xff0c;我们将准备好它们。 听起来是个好方法&#xff1f; 不&#xff0c;这不对。 这是一个坏主意&#xff0c;原因有一个&#xff1a…

一个路由器两个网段互通_如何判断两个IP地址是否在同一个网段?什么是子网掩码?...

前几天咱们了解&#xff1a;三种方法告诉你项目超过255个摄像机怎么设置IP?什么是公网ip&#xff1f;什么又是内网ip&#xff1f;为什么ip地址通常以192.168开头&#xff1f;也学习了&#xff1a;二、三层交换机与路由器的区别&#xff01;但是有好多人对IP这个概念还是不太清…

http 路径 |_HTTP 请求與响应的格式及 curl 命令使用

介绍 HTTP&#xff0c;主要内容有HTTP 请求包括哪些部分&#xff0c;如何用Chrome开发者工具查看 HTTP 请求内容HTTP 响应包括哪些部分&#xff0c;如何用Chrome开发者工具查看 HTTP 响应内容如何使用 curl 命令HTTP 请求的格式1 动词 路径 协议/版本 2 Key1: value1 2 Key2: v…

华为y7可以人脸识别吗_华为手机经常弹出“系统更新”提示,可以不更新吗?看完涨知识了...

众所周知&#xff0c;无论是手机&#xff0c;还是电脑&#xff0c;我们所使用的系统到了一定的时间&#xff0c;都会进行“系统更新”&#xff0c;尤其是我们使用的苹果手机、华为手机等&#xff0c;就经常会跳出提示&#xff0c;提醒用户“更新系统”&#xff0c;尤其是当我们…

Apache骆驼丝攻示例

如果您想监视&#xff0c;调试&#xff0c;排除流经路由的消息&#xff0c;而又不必从通道中永久消耗消息&#xff0c;那么就需要使用电线 。 有线分流器充当接收者列表&#xff0c;该列表消耗输入通道之外的消息并将其发布到两个输出通道。 第一个是作为主要信道的实际目的地…

参考文献中会议名称怎么缩写_期刊缩写查询总结

介绍英文论文写作中&#xff0c;经常会插入参考文献。那么参考文献中的期刊名称&#xff0c;时常需要使用缩写。但是有时候&#xff0c;查了半天&#xff0c;怎么也查不着&#xff0c;让人抓狂。今天小编总结了几个查询期刊缩写的网址&#xff0c;方便大家进行期刊缩写的查询。…

7. SVM松弛变量

我们之前讨论的情况都是建立在样例线性可分的假设上&#xff0c;当样例线性不可分时&#xff0c;我们可以尝试使用核函数来将特征映射到高维&#xff0c;这样很可能就可分了。然而&#xff0c;映射后我们也不能100%保证可分。那怎么办呢&#xff0c;我们需要将模型进行调整&…

mysql 8.0认证失败_解决mysql8.0因密码认证插件导致的链接不上

简介今天在迁移zabbix的数据库&#xff0c;每次链接到自己的mysql都报错&#xff0c;mysqlAuthentication plugin caching_sha2_password cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_passwordzabbix总是提示**** MySQL server is not available. Waiting 5 secon…

ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

近期项目中可能要用到Flash存取数据&#xff0c;并与JS互调&#xff0c;所以就看了一下ActionScript 3.0&#xff0c;现把学习结果分享一下&#xff0c;希望对新手有帮助。 目录 ActionScript 3.0简介 Hello World 文件读写 数据存储(SharedObject) 与JS互调 ActionScript 3.0简…

Quasar和Akka –比较

actor模型是用于容错和高度可扩展系统的设计模式。 角色是独立的工作程序模块&#xff0c;仅通过消息传递与其他角色进行通信&#xff0c;可以与其他角色隔离而失败&#xff0c;但是可以监视其他角色的故障并在发生这种情况时采取一些恢复措施。 参与者是简单&#xff0c;孤立但…

dlgdata.cpp错误提示 解决方案

1、在测试编写继承CStatic类组件时候&#xff0c;发现在调用调试过程中弹出一个错误&#xff0c;点忽略还可以继续运行。如下图&#xff1a; 2、dlgdata.cpp此文件是VS安装目录\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc中的文件&#xff0c;而出现此错误一般是所…

mysql主从复制时间配置_MySQL主从复制配置

环境CentOS 7.5Docker 1.13.1MySQL 8.0.16基于以上环境启动三个mysql容器&#xff0c;一个为master&#xff0c;二个为slavemaster和slave使用的mysql版本是完全一致的&#xff0c;未测试不同版本的mysql配置master编辑配置文件编辑master的配置文件my.cnf$ vim /usr/mysql/con…

C语言操作符优先级

转自&#xff1a;http://www.cnblogs.com/xiehy/archive/2010/02/04/1663825.html 优先级 运算符 含 义 要求运算 对象的个数 结合方向 1 () [] -> . 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 自左至右 2 ! 逻辑非运算符 1 (单目运算符)…