【Java并发】【AQS锁】锁在源码中的应用

news/2024/10/24 7:59:42/文章来源:https://www.cnblogs.com/kukuxjx/p/18498733

1  前言

本节主要记录下基于 AQS 衍生出来的一些常用锁比如:CountDownLatch、‌‌ReentrantLock、Semaphore、‌‌ReentrantReadWriteLock 等他们在源码中的一些应用,好记性不如烂笔头。‌

2  CountDownLatch

2.1  RocketMQ 中 Broker 向 所有NameServer 的注册

RocketMQ 路由注册是通过 Broker 与 NameServer 的心跳功能实现的。 Broker启动时向集群中所有的NameServ巳r发送心跳语句,每隔 30s 向集群中所有NameServer发送心跳包, NameServer 收到 Broker 心跳包时会更新 brokerLiveTable 缓存中 BrokerLivelnfo 的 lastUpdateTimestamp ,然后 Nam巳 Server 每隔 10s 扫描 brokerLiveTable,如果连续 !20s 没有收到心跳包, NameServer将移除该Broker 的路由信息同时关闭 Socket连接。

那么这里比如我有 4个 NameServer,是循环遍历一个一个注册么?其实不是,这里就用到了线程池 + CountDownLatch,我们看下:

public List<RegisterBrokerResult> registerBrokerAll(final String clusterName,final String brokerAddr,final String brokerName,final long brokerId,final String haServerAddr,final TopicConfigSerializeWrapper topicConfigWrapper,final List<String> filterServerList,final boolean oneway,final int timeoutMills,final boolean enableActingMaster,final boolean compressed,final Long heartbeatTimeoutMillis,final BrokerIdentity brokerIdentity) {final List<RegisterBrokerResult> registerBrokerResultList = new CopyOnWriteArrayList<>();List<String> nameServerAddressList = this.remotingClient.getAvailableNameSrvList();if (nameServerAddressList != null && nameServerAddressList.size() > 0) {final RegisterBrokerRequestHeader requestHeader = new RegisterBrokerRequestHeader();requestHeader.setBrokerAddr(brokerAddr);requestHeader.setBrokerId(brokerId);requestHeader.setBrokerName(brokerName);requestHeader.setClusterName(clusterName);requestHeader.setHaServerAddr(haServerAddr);requestHeader.setEnableActingMaster(enableActingMaster);requestHeader.setCompressed(false);if (heartbeatTimeoutMillis != null) {requestHeader.setHeartbeatTimeoutMillis(heartbeatTimeoutMillis);}RegisterBrokerBody requestBody = new RegisterBrokerBody();requestBody.setTopicConfigSerializeWrapper(TopicConfigAndMappingSerializeWrapper.from(topicConfigWrapper));requestBody.setFilterServerList(filterServerList);final byte[] body = requestBody.encode(compressed);final int bodyCrc32 = UtilAll.crc32(body);requestHeader.setBodyCrc32(bodyCrc32);// 创建一个计数器锁(数量为 nameServer 的个数)final CountDownLatch countDownLatch = new CountDownLatch(nameServerAddressList.size());// 循环遍历for (final String namesrvAddr : nameServerAddressList) {// 往线程池中扔任务brokerOuterExecutor.execute(new AbstractBrokerRunnable(brokerIdentity) {@Overridepublic void run0() {try {RegisterBrokerResult result = registerBroker(namesrvAddr, oneway, timeoutMills, requestHeader, body);if (result != null) {registerBrokerResultList.add(result);}LOGGER.info("Registering current broker to name server completed. TargetHost={}", namesrvAddr);} catch (Exception e) {LOGGER.error("Failed to register current broker to name server. TargetHost={}", namesrvAddr, e);} finally {// 计数器减1
                        countDownLatch.countDown();}}});}try {// 超时等待都注册完毕if (!countDownLatch.await(timeoutMills, TimeUnit.MILLISECONDS)) {LOGGER.warn("Registration to one or more name servers does NOT complete within deadline. Timeout threshold: {}ms", timeoutMills);}} catch (InterruptedException ignore) {}}return registerBrokerResultList;
}

可以看到是通过遍历,向线程池中执行任务,每个线程注册完会让锁减1,最后下边 await 等待所有的线程都注册完毕。

3  ReentrantLock

4  Semaphore

5  ReentrantReadWriteLock 

6  小结

归纳总结是对技术的巩固以及认识的增强,看看人家别人怎么用的,什么场景下用的,用法上跟自己的有什么不同,甚至在自己写业务的时候,是不是能直接借鉴下,哈哈哈,受益颇多都,所以大家也要学会总结积累哈。本节就主要记录下锁的一些源码应用(会持续增加),有理解不对的地方欢迎指正哈。

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

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

相关文章

如何查看织梦CMS网站源码中的数据库信息

1. 定位配置文件文件路径:织梦CMS V5.1:include/config_base.php 织梦CMS V5.3 及以上版本:data/common.inc.php2. 编辑配置文件使用文本编辑器打开 data/common.inc.php 文件,找到数据库连接配置部分。配置文件的内容通常如下所示:<?php // 数据库连接信息 $cfg_dbho…

PbootCMS错误提示:文件上传失败

错误提示:文件上传失败解决方案:检查上传文件夹(通常位于 /upload/)的写权限,确保Web服务器有写入权限。 检查PHP配置文件(php.ini)中的 upload_max_filesize 和 post_max_size 是否足够大。 检查文件类型和大小限制是否符合要求。扫码添加技术【解决问题】专注中小企业…

如何修改网站后台的地址?公司网站被修改怎么改?

如果公司的网站被未经授权的人员修改,你需要迅速采取措施来恢复网站并加强安全性。以下是一些步骤: 1. 确认问题检查网站:确认哪些部分被修改,记录下具体的改动。 通知相关人员:立即通知IT部门或负责网站维护的团队。2. 恢复网站备份恢复:如果有定期备份,从最近的备份中…

日志篇:模组日志总体介绍

​ 今天我们学习合宙模组日志总体介绍,以下进入正文。 一、本文讨论的边界 本文是对合宙 4G 模组, 以及 4G+GNSS 模组的日志功能的总体介绍。通过日志,可以对研发过程中,以及模组运行过程中的各种故障进行分析。 二、4G模组日志的几种类型界 4G 模组的日志有两种类型: 业务…

一篇讲透:模组典型上网业务的AT上网流程

​ 今天我们学习合宙模组典型上网业务的AT上网流程。 文末阅读原文,下载最新教程/固件。 一、简介 本文介绍了合宙4G模组的常用的AT指令和服务器交互的流程。 进一步详细的流程,参见各个模组的AT命令资料。 如果没有顺手的串口工具,推荐 [LLCOM | 能跑Lua代码的串口调试工具…

WPF 使用快捷键方式制作简易的 Word 上的 Latex 输入法

本文将告诉大家如何在 WPF 里面编写一个简易输入法软件,让这个输入法软件支持插入 Latex 格式的公式到 Word 内。核心原理是使用 Word 的快捷键插入公式编辑器,再通过剪贴板输入 Latex 格式的公式内容,再输入回车作为 Word 公式软件的界面效果如下:运行效果如下:本文以下为…

读数据工程之道:设计和构建健壮的数据系统18数据存储系统(上)

数据存储系统(上)1. 单机存储和分布式存储 1.1. 存储系统是存在于原材料之上的抽象层次 1.2. 磁盘是一种原始存储材料,而主要的云对象存储平台和HDFS是利用磁盘的存储系统 1.3. 随着数据存储和访问模式变得越来越复杂,并超出了单一服务器能做到的支持,将数据分布到一个以上…

2024.10.24 鲜花

多次查询给定集合是否存在任一给定子集多次查询给定集合是否存在任一给定子集Re:End of a Dream先考虑经典例题 DZY Loves Chinese II 考虑其做法:随机赋值非树边,用返祖边来平衡使其权值为 \(0\),线性基维护。 考虑扩展,发现集合中并不存在一个唯一元素用来平衡,考虑在每…

指令

带v-的特殊属性即为指令,常见的指令有v-if,v-show,v-html,v-text,v-slot,v-bind,v-on,v-model等等,也可自定义指令。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。除了name为必须外,其他的都可以没有,也可以有,修饰符可以有多个; v-focus v-aa.bb v-aa:aa.b…

温故知新,基于播客形式学习英语之EnglishPod 365, Elementary初级C集合(音频、原文、讲解)

简介 Enishpod是一家公司叫做Praxis Language推出的收费讲座,相比较ESLPod, EnishPod为常速。Enishpod极具趣味性,两位主持人Marco和Amira的讲解很生动幽默,完全有别于新概念类型听力的乏味。同时,Enishpod分了不同的难度级别,基础较差可以先选择B级和C级。 Elementary - …

网课视频课程下载神器,学无止下载器,快过期的课程有救了!

有多少小伙伴像我一样,准备在假期好好学点兴趣以内的东西,结果发现花费好几百块买的课居然过期了打开之后课程已经过期,无法观看了(网易云课堂购买的课程过期后无法观看了。。。)又想学习,又不想再浪费钱,该怎么办呢?一顿操作猛如虎,费了半天功夫装了X猴,装了各种插件…

手把手教你如何下载智慧职教(职教云)视频课程课件资料

前言:很多同学都想知道智慧职教(职教云)中课程视频资料怎么下载,但是智慧职教中某个课程的目录中展示的视频和资料是不提供直接下载方式的,所以下面就教大家如何用学无止下载器下载目录中展示的视频资料,包括MP4,PPT和PDF。 一、电脑登录智慧职教网页版 网页版智智慧职教…