当前位置: 首页 > news >正文

第二十章 Java多线程--JUC并发工具-CountDownLatch

目录

一、CountDownLatch基础概念

CountDownLatch 的核心概念

CountDownLatch 的常用方法

场景一:主线程等待多个子线程执行完毕

场景二:实现多个线程同时开始执行任务

场景三:统计报表优化

CountDownLatch 的局限性

结论

二、CountDownLatch深入理解

1 CountDownLatch介绍

1.2 CountDownLatch应用

1.3 CountDownLatch源码分析

1.3.1 有参构造

1.3.2 await方法

1.3.3 countDown方法


一、CountDownLatch基础概念

CountDownLatch 是 Java 并发工具包中一个非常实用的工具类,它通过定义一个计数器和阻塞队列实现了线程间的同步与协作。4 它的主要作用是让一个或多个线程等待其他线程的一系列操作完成。这种机制特别适用于需要确保一系列任务全部完成后再执行特定操作的场景。

CountDownLatch 的核心概念

CountDownLatch 初始化时需要提供一个整数参数作为计数器,这个整数代表了线程需要调用 countDown() 方法的次数。每当一个任务线程完成其任务后,都会调用 countDown() 方法减少计数器的值。当计数器的值递减到 0 时,所有因调用 await() 方法而被阻塞的线程将被唤醒并继续执行。

CountDownLatch 的常用方法

CountDownLatch(int count): 构造方法,创建一个值为 count 的计数器。

void await(): 阻塞当前线程,直到计数器的值为 0。如果计数器已经是 0,则该方法立即返回。

boolean await(long timeout, TimeUnit unit): 类似于 await(),但会等待指定的时间。如果在指定时间内计数器未达到 0,则返回 false。

void countDown(): 减少计数器的值。当计数器递减到 0 时,会唤醒所有等待的线程。

long getCount(): 返回当前计数器的值。

CountDownLatch 的应用场景

场景一:主线程等待多个子线程执行完毕

这是 CountDownLatch 最常见的应用场景之一。例如,一个服务启动时,主线程可能需要等待多个组件加载完毕才能继续执行。在这种情况下,可以使用 CountDownLatch 来确保所有组件加载完毕后再继续。

场景二:实现多个线程同时开始执行任务

另一个典型的使用场景是实现多个线程的最大并行性,即让多个线程在同一时刻开始执行任务。这类似于赛跑中的发令枪,所有选手都在听到枪声后同时起跑。通过使用 CountDownLatch,可以确保多个线程在同一时间点开始执行任务。

场景三:统计报表优化

在一些需要统计数据的应用中,可能会涉及到大量的计算和数据库查询。如果这些任务以串行方式执行,将会大大增加页面加载时间。通过将这些任务分配给多个线程并行处理,并使用 CountDownLatch 确保所有任务完成后再聚合结果,可以显著提高系统的响应速度。

CountDownLatch 的局限性

虽然 CountDownLatch 提供了强大的线程同步能力,但它也有一些局限性。最重要的一点是,CountDownLatch 是一次性使用的,一旦计数器递减到 0,它不能被重置。这意味着如果需要重复使用相同的同步机制,就需要创建一个新的 CountDownLatch 实例。

结论

CountDownLatch 是 Java 并发编程中不可或缺的一部分,它提供了灵活的线程同步机制,使得多线程编程变得更加简洁高效。通过合理利用 CountDownLatch,开发者可以轻松解决线程间的同步问题,提高程序的并发性能。然而,使用时也需要注意其一次性使用的特点,避免不必要的资源浪费。

二、CountDownLatch深入理解

1 CountDownLatch介绍

CountDownLatch就是JUC包下的一个工具,整个工具最核心的功能就是计数器。

如果有三个业务需要并行处理,并且需要知道三个业务全部都处理完毕了。

需要一个并发安全的计数器来操作。

CountDownLatch就可以实现。

给CountDownLatch设置一个数值。可以设置3。

每个业务处理完毕之后,执行一次countDown方法,指定的3每次在执行countDown方法时,对3进行-1。

主线程可以在业务处理时,执行await,主线程会阻塞等待任务处理完毕。

当设置的3基于countDown方法减为0之后,主线程就会被唤醒,继续处理后续业务。

当咱们的业务中,出现2个以上允许并行处理的任务,并且需要在任务都处理完毕后,再做其他处理时,可以采用CountDownLatch去实现这个功能。

1.2 CountDownLatch应用

模拟有三个任务需要并行处理,在三个任务全部处理完毕后,再执行后续操作

CountDownLatch中,执行countDown方法,代表一个任务结束,对计数器 - 1

执行await方法,代表等待计数器变为0时,再继续执行

执行await(time,unit)方法,代表等待time时长,如果计数器不为0,返回false,如果在等待期间,计数器为0,方法就返回true

一般CountDownLatch更多的是基于业务去构建,不采用成员变量。

static ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);static CountDownLatch countDownLatch = new CountDownLatch(3);public static void main(String[] args) throws InterruptedException {System.out.println("主业务开始执行");sleep(1000);executor.execute(CompanyTest::a);executor.execute(CompanyTest::b);executor.execute(CompanyTest::c);System.out.println("三个任务并行执行,主业务线程等待");// 死等任务结束// countDownLatch.await();// 如果在规定时间内,任务没有结束,返回falseif (countDownLatch.await(10, TimeUnit.SECONDS)) {System.out.println("三个任务处理完毕,主业务线程继续执行");}else{System.out.println("三个任务没有全部处理完毕,执行其他的操作");}
}private static void a() {System.out.println("A任务开始");sleep(1000);System.out.println("A任务结束");countDownLatch.countDown();
}
private static void b() {System.out.println("B任务开始");sleep(1500);System.out.println("B任务结束");countDownLatch.countDown();
}
private static void c() {System.out.println("C任务开始");sleep(2000);System.out.println("C任务结束");countDownLatch.countDown();
}private static void sleep(long timeout){try {Thread.sleep(timeout);} catch (InterruptedException e) {e.printStackTrace();}
}

1.3 CountDownLatch源码分析

保证CountDownLatch就是一个计数器,没有什么特殊的功能,查看源码也只是查看计数器实现的方式

发现CountDownLatch的内部类Sync继承了AQS,CountDownLatch就是基于AQS实现的计数器。

AQS就是一个state属性,以及AQS双向链表

猜测计数器的数值实现就是基于state去玩的。

主线程阻塞的方式,也是阻塞在了AQS双向链表中。

1.3.1 有参构造

就是构建内部类Sync,并且给AQS中的state赋值

// CountDownLatch的有参构造
public CountDownLatch(int count) {// 健壮性校验if (count < 0) throw new IllegalArgumentException("count < 0");// 构建内部类,Sync传入countthis.sync = new Sync(count);
}// AQS子类,Sync的有参构造
Sync(int count) {// 就是给AQS中的state赋值setState(count);
}
1.3.2 await方法

await方法就时判断当前CountDownLatch中的state是否为0,如果为0,直接正常执行后续任务

如果不为0,以共享锁的方式,插入到AQS的双向链表,并且挂起线程

// 一般主线程await的方法,阻塞主线程,等待state为0
public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);
}// 执行了AQS的acquireSharedInterruptibly方法
public final void acquireSharedInterruptibly(int arg) throws InterruptedException {// 判断线程是否中断,如果中断标记位是true,直接抛出异常if (Thread.interrupted())throw new InterruptedException();if (tryAcquireShared(arg) < 0)// 共享锁挂起的操作doAcquireSharedInterruptibly(arg);
}// tryAcquireShared在CountDownLatch中的实现
protected int tryAcquireShared(int acquires) {// 查看state是否为0,如果为0,返回1,不为0,返回-1return (getState() == 0) ? 1 : -1;
}private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {// 封装当前先成为Node,属性为共享锁final Node node = addWaiter(Node.SHARED);boolean failed = true;try {for (;;) {final Node p = node.predecessor();if (p == head) {int r = tryAcquireShared(arg);if (r >= 0) {setHeadAndPropagate(node, r);p.next = null; // help GCfailed = false;return;}}// 在这,就需要挂起当前线程。if (shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt())throw new InterruptedException();}} finally {if (failed)cancelAcquire(node);}
}
1.3.3 countDown方法

countDown方法本质就是对state - 1,如果state - 1后变为0,需要去AQS的链表中唤醒挂起的节点

// countDown对计数器-1
public void countDown() {// 是-1。sync.releaseShared(1);
}// AQS提供的功能
public final boolean releaseShared(int arg) {// 对state - 1if (tryReleaseShared(arg)) {// state - 1后,变为0,执行doReleaseShareddoReleaseShared();return true;}return false;
}
// CountDownLatch的tryReleaseShared实现
protected boolean tryReleaseShared(int releases) {// 死循环是为了避免CAS并发问题for (;;) {// 获取stateint c = getState();// state已经为0,直接返回falseif (c == 0)return false;// 对获取到的state - 1int nextc = c-1;// 基于CAS的方式,将值赋值给stateif (compareAndSetState(c, nextc))// 赋值完,发现state为0了。此时可能会有线程在await方法处挂起,那边挂起,需要这边唤醒return nextc == 0;}
}// 如何唤醒在await方法处挂起的线程
private void doReleaseShared() {// 死循环for (;;) {// 拿到headNode h = head;// head不为null,有值,并且head != tail,代表至少2个节点// 一个虚拟的head,加上一个实质性的Nodeif (h != null && h != tail) {// 说明AQS队列中有节点int ws = h.waitStatus;// 如果head节点的状态为 -1.if (ws == Node.SIGNAL) {// 先对head节点将状态从-1,修改为0,避免重复唤醒的情况if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))continue;  // 正常唤醒节点即可,先看head.next,能唤醒就唤醒,如果head.next有问题,从后往前找有效节点unparkSuccessor(h);}// 会在Semaphore中谈到这个位置else if (ws == 0 &&!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))continue;        }// 会在Semaphore中谈到这个位置if (h == head)  break;}
}

相关文章:

第二十章 Java多线程--JUC并发工具-CountDownLatch

目录 一、CountDownLatch基础概念 CountDownLatch 的核心概念 CountDownLatch 的常用方法 场景一&#xff1a;主线程等待多个子线程执行完毕 场景二&#xff1a;实现多个线程同时开始执行任务 场景三&#xff1a;统计报表优化 CountDownLatch 的局限性 结论 二、Count…...

限制对 etcd 的访问范围是确保 Kubernetes 集群安全的一个重要环节。

限制对 etcd 的访问范围是确保 Kubernetes 集群安全的一个重要环节。通常&#xff0c;etcd 只应当对 Kubernetes 控制平面的组件&#xff08;如 API Server、Controller Manager、Scheduler 等&#xff09;以及某些维护工具&#xff08;如备份工具&#xff09;开放访问权限&…...

shell脚本基础学习_总结篇(完结)

细致观看可以&#xff0c;访问shell脚本学习专栏&#xff0c;对应章节会有配图https://blog.csdn.net/2201_75446043/category_12833287.html?spm1001.2014.3001.5482 导语 一、shell脚本简介 1. 定义&#xff1a; 2. 主要特点&#xff1a; 3. shell脚本的基本结构 4. S…...

Linux之网络基础

网络发展 网络的发展可以从人与人之间的工作模式开始谈起, 人与人的工作模式反应了机器与机器的工作模式: 1. 独立模式: 在网络发展的早期计算机间处于独立模式, 计算机之间相互独立 最开始计算机之间是独立运行的, 数据之间的交互需要人用软盘等存储介质拷贝过去, 一般涉及…...

《Vue零基础入门教程》第十课:属性绑定指令

往期内容 《Vue零基础入门教程》第一课&#xff1a;Vue简介 《Vue零基础入门教程》第二课&#xff1a;搭建开发环境 《Vue零基础入门教程》第三课&#xff1a;起步案例 《Vue零基础入门教程》第四课&#xff1a;应用实例 《Vue零基础入门教程》第五课&#xff1a;挂载 《…...

RabbitMQ 安装延迟队列插件 rabbitmq_delayed_message_exchange

前言&#xff1a; RabbitMQ 延迟队列插件&#xff08;rabbitmq_delayed_message_exchange&#xff09;是一个社区开发的插件&#xff0c;它为 RabbitMQ 添加了支持延迟消息的功能。通过这个插件&#xff0c;用户可以创建一种特殊的交换机类型 x-delayed-message&#xff0c;该…...

MATLAB中Simulink的基础知识

Simulink是MATLAB中的一种可视化仿真工具&#xff0c; 是一种基于MATLAB的框图设计环境&#xff0c;是实现动态系统建模、仿真和分析的一个软件包&#xff0c;被广泛应用于线性系统、非线性系统、数字控制及数字信号处理的建模和仿真中。 Simulink提供一个动态系统建模、仿真和…...

Swift——单例模式

单例是软件设计常用的一种模式&#xff0c;它的核心结构中只有一个被称为单例的特殊类&#xff0c;通过单例模式可以保证应用该模式的类只有一个实例化对象&#xff0c;其作用就是能够使类中的一个对象成为系统中的唯一实例。 单例的特点&#xff1a; 某个类只有一个实例化对象…...

百度智能云千帆大模型平台引领企业创新增长

本文整理自百度世界大会 2024——「智能跃迁 产业加速」论坛的同名演讲。 更多大会演讲内容&#xff0c;请访问&#xff1a; https://baiduworld.baidu.com 首先&#xff0c;跟大家分享一张图&#xff0c;这个是我们目前大模型应用落地的场景分布。可以看到&#xff0c;大模型…...

scala统计词频

目标&#xff1a;统计词频 &#xff08;1&#xff09;从文件1.tst&#xff0c;读入内容&#xff0c;保存在一个字符串中。 &#xff08;2&#xff09;统计字符串中&#xff0c;每个单词出现的频率 &#xff08;3&#xff09;对结果进行排序 &#xff08;4&#xff09;把最后…...

CTF之密码学(费纳姆密码)

一、作为二进制替换密码的费纳姆密码 定义&#xff1a;费纳姆密码是一种由二进制产生的替换密码&#xff0c;也被称为弗纳姆密码&#xff08;Vernam cipher&#xff09;。它采用二进制表示法&#xff0c;将明文转化为二进制数字&#xff0c;并通过与密钥进行模2加法运算来产生密…...

postgresql按照年月日统计历史数据

1.按照日 SELECT a.time,COALESCE(b.counts,0) as counts from ( SELECT to_char ( b, YYYY-MM-DD ) AS time FROM generate_series ( to_timestamp ( 2024-06-01, YYYY-MM-DD hh24:mi:ss ), to_timestamp ( 2024-06-30, YYYY-MM-DD hh24:mi:ss ), 1 days ) AS b GROUP BY tim…...

Python 网络爬虫进阶:动态网页爬取与反爬机制应对

在上一篇文章中&#xff0c;我们学习了如何使用 Python 构建一个基本的网络爬虫。然而&#xff0c;在实际应用中&#xff0c;许多网站使用动态内容加载或实现反爬机制来阻止未经授权的抓取。因此&#xff0c;本篇文章将深入探讨以下进阶主题&#xff1a; 如何处理动态加载的网…...

YOLOv11融合PIDNet中的PagFM模块及相关改进思路

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《PIDNet: A Real-time Semantic Segmentation Network Inspired by PID Controllers》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/pdf/2…...

使用Python实现自动化邮件通知:当长时程序运行结束时

使用Python实现自动化邮件通知&#xff1a;当长时程序运行结束时 前提声明 本代码仅供学习和研究使用&#xff0c;不得用于商业用途。请确保在合法合规的前提下使用本代码。 目录 引言项目背景项目设置代码分析 导入所需模块定义邮件发送函数发送邮件 实现步骤结语全部代码…...

smb cifs samba smbpasswd 笔记241127

smb cifs samba smbpasswd 笔记241127 SMB、CIFS和Samba都是与文件共享相关的技术&#xff0c;它们在不同的层面上发挥着作用。以下是关于SMB、CIFS和Samba的详细解释&#xff1a; SMB&#xff08;Server Message Block&#xff09; 定义&#xff1a;SMB&#xff08;Server …...

Spring MVC练习(前后端分离开发实例)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:二十五弦弹夜月&#xff0c;不胜清怨却飞来&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…...

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo&#xff0c;想赶快在电脑上 pip install 一下跑起来&#xff0c;发现因为 python 的 venv、conda 环境还挺费劲的&#xff0c;因为随着时间的发展&#xff0c;之前记得很清楚的 venv、conda 的用法&#xff0c;不经常使用&#xff0c;半天跑不起…...

英语知识网站开发:Spring Boot框架应用

3系统分析 3.1可行性分析 通过对本英语知识应用网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本英语知识应用网站采用SSM框架&#xff0c;JAVA作为开发语…...

Pandas 数据读取与导出

Pandas 是一个强大的 Python 库&#xff0c;用于数据处理和分析。它提供了许多函数来读取和导入数据&#xff0c;支持多种文件格式&#xff0c;如 CSV、Excel、SQL 数据库、JSON 等。以下是一些常用的数据读取和导出方法&#xff1a; 常用方法 格式文件格式读取函数写入&…...

Day49 | 动态规划 :线性DP 判断子序列两个字符串的删除操作

Day49 | 动态规划 &#xff1a;线性DP 判断子序列&&两个字符串的删除操作 动态规划应该如何学习&#xff1f;-CSDN博客 动态规划学习&#xff1a; 1.思考回溯法&#xff08;深度优先遍历&#xff09;怎么写 注意要画树形结构图 2.转成记忆化搜索 看哪些地方是重复…...

HDR视频技术之三:色度学与颜色空间

HDR 技术的第二个理论基础是色度学。从前面的内容中可以了解到&#xff0c;光学以及人类视觉感知模型为人类提供了解释与分析人类感知亮度的理论基础&#xff0c;但是 HDR 技术不仅仅关注于提升图像与视频的亮度范围&#xff0c;同时也关注于提供更加丰富的色彩。因此&#xff…...

nginx和netcore加载常见的3D模型

背景 数字孪生带火了3D版的Web世界&#xff0c;3D模型格式也是众多&#xff0c;常见的glb适合web传输&#xff0c;fbx&#xff0c;gltf&#xff0c;obj&#xff0c;unity等常用于模型编辑和处理。我们在用netcore或者wasm加载这些3D模型文件时&#xff0c;一般都需要手工增加M…...

ABAP开发学习——标准GUI状态模板的复制

补充一下创建了GUI状态后复制标准状态的方法 首先创建GUI状态 此时按钮全部都是空的 点击顶部的附加-调整模板 选择列表查看器 应用成功&#xff0c;下一步点击激活即可 另外需要注意&#xff0c;功能键中的三个图标的代码并不是习惯性写的”BACK、EXIT、CANCEL",在这个标…...

酷!用豆包MarsCode 写了一个五子棋小游戏

作者&#xff1a;一起重学前端 前言 2017 年&#xff0c;当时大学三本毕业前端工作一年&#xff0c;去深圳找工作面试&#xff0c;在拉勾上海投&#xff0c;接到某公司前端开发团队回复询问邮箱账号&#xff0c;喜滋滋的以为可以有面试了。一看邮箱&#xff0c;抛给我一道面试…...

IntelliJ IDEA 中,自动导包功能

在 IntelliJ IDEA 中&#xff0c;自动导包功能可以极大地提高开发效率&#xff0c;减少手动导入包所带来的繁琐和错误。以下是如何在 IntelliJ IDEA 中设置和使用自动导包功能的详细步骤&#xff1a; 一、设置自动导包 打开 IntelliJ IDEA&#xff1a; 启动 IntelliJ IDEA 并打…...

c#异步编程(async/await)

注&#xff1a;下文摘自ChatGPT&#xff0c;总结与案例都非常完善&#xff0c;可以快速理解并应用 0&#xff1a;使用场景 在winform界面程序中&#xff0c;在ui操作中涉及到一些耗时的等待操作&#xff0c;使用线程自己处理已经显得力不从心&#xff0c;如何能更好的实现&am…...

使用vcpkg自动链接tinyxml2时莫名链接其他库(例如boost)

使用vcpkg自动链接tinyxml2时莫名链接其他库&#xff08;例如boost&#xff09; vcpkg的自动链接功能非常方便&#xff0c;但在某些情况下会出现过度链接的问题。 链接错误症状 以tinyxml2为例&#xff0c;程序中调用tinyxml2的函数后&#xff0c;若vcpkg中同时存在opencv和…...

cocoscreater3.8.4生成图集并使用

1.安装texturepacker&#xff0c;去官网下载https://www.codeandweb.com/texturepacker 2.将图片拖动进来&#xff0c;即可自动生成精灵表&#xff0c;这里输出选用cocos2d-x&#xff0c;打包用免费版的“基本”就行&#xff0c;高级模式是收费的&#xff0c;然后点击“发布精…...

Ettercap工具使用说明

文章目录 Ettercap 简介Ettercap 的主要功能Ettercap 的安装在 Kali Linux&#xff08;或基于 Debian 的系统&#xff09;上安装&#xff1a;在其他操作系统上&#xff1a; Ettercap 的使用方式1. 基本模式2. MITM 攻击ARP 欺骗DNS 欺骗 3. 嗅探模式 常用插件防御建议 Ettercap…...

Linux 如何创建逻辑卷并使用

一、逻辑卷的介绍 生成环境中逻辑卷使用率很高 逻辑卷的诞生&#xff1a;如果对磁盘直接使用fdisk分区&#xff0c;那么这中分区&#xff0c;我们叫做Linux的标准分区&#xff0c;Linux的标准分区格式化成文件系统之后&#xff0c;挂载使用&#xff0c;那么一旦文件系统的空间…...

laravel-operate

php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear 1、查看artisan所有命令&#xff1b; php artisan list 2、查看命令描述及参数和选项&#xff1b; php artisan&#xff08;n.工匠、技工&#xff09; help migration&…...

探索Python WebSocket新境界:picows库揭秘

文章目录 探索Python WebSocket新境界&#xff1a;picows库揭秘第一部分&#xff1a;背景介绍第二部分&#xff1a;picows库概述第三部分&#xff1a;安装picows库第四部分&#xff1a;简单库函数使用方法第五部分&#xff1a;场景应用第六部分&#xff1a;常见Bug及解决方案第…...

海康VsionMaster学习笔记(学习工具+思路)

一、前言 VisionMaster算法平台集成机器视觉多种算法组件&#xff0c;适用多种应用场景&#xff0c;可快速组合算法&#xff0c;实现对工件或被测物的查找测量与缺陷检测等。VM算法平台依托海康威视在图像领域多年的技术积淀&#xff0c;自带强大的视觉分析工具库&#xff0c;可…...

Java面试题、八股文——JVM篇最终篇

1.如何选择垃圾收集器&#xff1f; 选择合适的垃圾收集器&#xff08;Garbage Collector, GC&#xff09;对于优化Java应用程序的性能至关重要。不同的应用场景和系统需求可能需要不同类型的垃圾收集器来满足。以下是一些考虑因素以及常见的垃圾收集器选项&#xff0c;帮助您做…...

C++ 11重点总结2

1C11多线程 主要对少用的知识点进行详细描述&#xff0c;用的多的就给示例。照猫画虎 #include<thread> // 默认构造函数 thread() // 初始化构造函数 template<class Fn, class... Args> explicit thread(Fn&& fn, Args&&... args) // 移动构造…...

什么是 C++ 中的函数对象?它有什么特点?

在 C 中&#xff0c;函数对象&#xff08;Function Object&#xff09;是一种可调用对象&#xff0c;它允许像函数一样被调用&#xff0c;但实际上它可能并不是真正的函数。函数对象可以是以下几种类型之一&#xff1a; 普通函数&#xff1a; 一个普通的、定义在命名空间或类…...

Golang 反射

一、Go反射的应用场景 &#xff08;一&#xff09;对象序列化和反序列化 场景描述 在处理网络通信&#xff0c;数据存储等场景中&#xff0c;需要将对象转换为字节流&#xff08;序列化&#xff09;以便传输或存储&#xff0c;在接收端再将字节流转换回对象&#xff08;反序列…...

hhdb数据库介绍(10-7)

OEM管理 为方便更换管理平台的产品Logo以及产品名称信息。引入“OEM管理功能”对外提供可视化更新Logo以及产品名称信息的入口。 功能入口&#xff1a; 具有管理权限的用户登录平台&#xff0c;通过 OEM管理的超链接进入功能页面&#xff0c;超链接路径需要在原访问页面url的…...

RabbitMQ的预取值详解

RabbitMQ的预取值&#xff08;Prefetch Value&#xff09;是一个关键概念&#xff0c;它决定了消费者在从队列中获取消息时&#xff0c;一次性可以获取的消息数量。这一机制对于优化消息分发和消费者的负载均衡至关重要。 什么是RabbitMQ的预取值&#xff1f; 预取值是指消费者…...

mysql 触发器进入历史

一、触发器 MySQL 触发器&#xff08;Triggers&#xff09;是一种数据库对象&#xff0c;它与表关联&#xff0c;能在特定的事件&#xff08;如插入、更新或删除&#xff09;发生时自动执行一些指定的操作。使用触发器可以帮助我们自动维护数据库的完整性、一致性&#xff0c;…...

通过数巅能源大模型降本增效

在能源行业中&#xff0c;数据的有效利用对于企业的决策和运营至关重要。随着业务的发展&#xff0c;企业面临着数据分散、数据分析效率低、报告生成耗时等问题&#xff0c;制约了企业的发展和竞争力的提升。 数巅能源大模型解决方案 数巅科技推出了能源大模型解决方案&#x…...

如何编写出色的技术文档

目录 ​编辑 1. 明确文档目的和受众 目的的重要性 了解受众 2. 收集和组织信息 信息收集的技巧 组织信息 3. 规划文档结构 结构规划的重要性 结构规划的步骤 4. 编写内容 语言和风格 内容的组织 编写技巧 5. 审阅和测试 审阅的重要性 测试的必要性 6. 版本控…...

摄像头原始数据读取——gstreamer(gst_parse_launch)

摄像头原始数据读取——gstreamer(gst_parse_launch) #include <stdio.h> #include <string.h> #include <stdlib.h>#ifdef __cplusplus extern "C" { #endif#include <gst/gst.h>#ifdef __cplusplus }; #endifstatic gboolean bus_msg_tim…...

矩阵/矩阵乘法/特征值/特征向量的讲解

线性代数里有很多的概念&#xff0c;很多概念是有几何意义的&#xff0c;了解了几何意义可能会更好的理解各种概念及其相互之间的关系。 矩阵&#xff1a; 矩阵是一个变换&#xff0c;一个坐标系到另一个坐标系的变换。矩阵里的各个参数&#xff0c;代表了如何进行变换。 矩阵…...

docker-compose搭建xxl-job、mysql

docker-compose搭建xxl-job、mysql 1、搭建docker以及docker-compose2、下载xxl-job需要数据库脚本3、创建文件夹以及docker-compose文件4、坑来了5、正确配置6、验证-运行成功 1、搭建docker以及docker-compose 略 2、下载xxl-job需要数据库脚本 下载地址&#xff1a;https…...

《图像形态学运算全解析:原理、语法及示例展示》

简介&#xff1a; 本文详细介绍了图像形态学中的多种运算&#xff0c;包括腐蚀、膨胀、开运算、闭运算、形态学梯度运算、礼帽运算以及黑帽运算。分别阐述了各运算的原理、语法格式&#xff0c;并通过 Python 代码结合具体示例图片&#xff08;如erode.JPG、dilate.JPG、close.…...

【面试分享】C++ 中结构体(struct)和类(class)的区别

在 C中&#xff0c;结构体&#xff08;struct&#xff09;和类&#xff08;class&#xff09;有一些相似之处&#xff0c;但也存在一些重要的区别&#xff1a; 一、默认访问权限 结构体&#xff1a; 在 C中&#xff0c;结构体的默认成员访问权限是public&#xff08;公有&…...

Rk3588 onnx转rknn,出现 No module named ‘rknn‘

一、操作步骤&#xff1a; rk3588 需要将yolo11 的模型onnx转rknn。 https://github.com/airockchip/rknn_model_zoo/tree/main/examples/yolo11 这个是用yolo11训练的模型&#xff0c;有80种类型。 完整下载下来后&#xff0c;在按文档描述下载模型下来&#xff1a; 然后进…...

HarmonyOS:@Provide装饰器和@Consume装饰器:与后代组件双向同步

一、前言 Provide和Consume&#xff0c;应用于与后代组件的双向数据同步&#xff0c;应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递&#xff0c;Provide和Consume摆脱参数传递机制的束缚&#xff0c;实现跨层级传递。 其中Provi…...