JavaEE初阶第四期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(二)
专栏:JavaEE初阶起飞计划
个人主页:手握风云
目录
一、Thread类及常用方法
2.1. Thread的常见构造方法
2.2. Thread的常见属性
2.3. 启动一个线程
2.4. 中断一个线程
2.5. 等待一个线程
2.6. 休眠当前线程
一、Thread类及常用方法
2.1. Thread的常见构造方法
方法 | 说明 |
Thread() | 创建线程对象 |
Thread(Runnable target) | 使用Runnable对象创建线程对象 |
Thread(String name) | 创建线程对象并命名 |
Thread(Runnable target, String name) | 使用Runnable对象创建线程对象并命名 |
name参数用来给线程取名字。名字叫啥,不影响线程的执行,不同的名字更利于调试。
public class Demo1 {public static void main(String[] args) {// 创建线程对象Thread t1 = new Thread() {@Overridepublic void run() {while (true) {System.out.println("hello t1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}};t1.start();// 使用Runnable对象创建线程Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("hello t2");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});t2.start();// 创建线程对象并使用name参数命名Thread t3 = new Thread("这是我的t3线程") {@Overridepublic void run() {while (true) {System.out.println("hello t3");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};t3.start();// 使用Runnable对象创建线程并使用name参数命名Thread t4 = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("hello t4");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}, "这是我的t4线程");t4.start();}
}
如上图所示,我们会发现这里没有main主线程。这是因为start执行完毕后,main方法就执行结束了,对应的主线程也结束了,随之自动销毁。
对于ThreadGroup线程组,把若干个线程放到同一个组里面,这样的话就可以给每个组里的线程设置相同的属性。但这个并不常用,更多的是用到线程池。
2.2. Thread的常见属性
属性 | 获取方法 |
ID | getID() |
名称 | getName() |
状态 | getState() |
优先级 | getPriority() |
是否为后台进程 | isDaemon() |
是否存活 | isAlive() |
是否被中断 | isInterrupted |
ID是线程的唯一标识,不同的线程不会重复。获取名称常用于调试和日志记录,帮助开发者了解当前正在执行的线程名称。线程状态可以分为NEW(新建)、RUNNABLE(就绪/运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超时等待)和TERMINATED(消亡)。线程的优先级是一个整数,表示线程在运行时的重要程度。Java中线程的优先级范围从1到10,其中1是最低优先级,10是最高优先级。
isDaemon()方法用于判断线程是否为后台线程。后台进程,当线程没运行完,进程可以就结束,无论有多少个后台进程,都无法阻止进程结束。对应的还有前台进程,当线程没运行完,进程就不会结束,当有多个线程时,就得所有线程结束才能结束进程。main线程和自己创建的线程都是前台进程,剩下的都是后台进程。如果一个线程做得任务很重要,这个任务必须要做完,应该设置为前台线程;相反如果任务无关紧要,就可以设置为后台进程。isAlive()方法用于判断线程是否在运行。当一个线程启动后,它会一直运行,直到run()方法执行完毕或者线程被中断。isInterrupted()方法用于判断线程是否被中断。当一个线程被中断时,它的中断状态会被设置为true,可以通过isInterrupted()方法来检查这个状态。
public class Demo2 {public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"This is mine");t.start();System.out.println(t.getId());System.out.println(t.getName());System.out.println(t.getState());System.out.println(t.getPriority());System.out.println(t.isDaemon());System.out.println(t.isAlive());System.out.println(t.isInterrupted());}
}
2.3. 启动一个线程
调用start()方法会真正调用系统中的API,线程跑起来之后就会自动执行到run()。调用start的方法本身就很快,一旦执行start,代码就会自动往下执行,不会产生任何的阻塞等待。
public class Demo2 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("hello thread");});t.start();System.out.println("hello main");}
}
执行结果如上图所示,大部分情况下都是hello main在前,也可能会有例外。这是因为在start之后,main线程和t线程两个执行流,是一个并发执行关系。操作系统对于线程的调度是随机的,如果执行完start恰好被调度出CPU,此时CPU下次执行main还是t就不确定了。
一个线程对象只能被启动一次。线程执行了start之后,就是就绪状态或者阻塞状态,对于这两种状态,不能再启动了。
public class Demo2 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("hello thread");});t.start();System.out.println("hello main");t.start();}
}
总结:使用Interrupt方法时,t线程没有使用sleep等阻塞操作,t的isInterrupted()方法返回true,通过循环条件结束t线程;t线程使用了sleep等阻塞操作,t的isInterrupted()方法也会返回true,但sleep如果被提前唤醒,抛出InterruptedException异常。
2.4. 中断一个线程
这里不要跟操作系统里的中断搞混,线程的中断准确来说应该叫“打断”或者“终止”。正常情况下,一个线程需要把入口方法执行完,才能够使线程结束。但有时候,我们希望线程能够提前终止,尤其是在线程休眠的时候。这时就需要通过打断线程的操作,也需要线程本身代码做出配合。
- 通过变量
public class Demo3 {public static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (flag) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();System.out.println("hello main");Thread.sleep(5000);flag = false;System.out.println("让t线程终止");}
}
- 通过内置的标志位isInterrupted()
Thread对象中,包含了一个布尔变量,如果为false,说明没有人去尝试终止这个线程;如果为true,说明有人尝试终止。
public class Demo4 {public static void main(String[] args) {Thread t = new Thread(() -> {while (!t.isInterrupted()) {}});}
}
此时这个代码是有错的,原因如下图所示:变量t未初始化,因为此处针对lambda表达式的定义是在new Thread()之前。
我们可以使用Thread类内部的静态方法currentThread(),用于获取对当前正在执行的线程对象的引用。
public class Demo4 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {// 当线程t没有被中断时,打印"hello thread"while (!Thread.currentThread().isInterrupted()) {System.out.println("hello thread");}});t.start();// 主线程休眠4秒Thread.sleep(4000);// 中断线程t// 把标志位false改为truet.interrupt();}
}
这里可能打印的结果有点多,我们也可以让t线程休眠1秒。
public class Demo4 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {// 当线程t没有被中断时,打印"hello thread"while (!Thread.currentThread().isInterrupted()) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();// 主线程休眠4秒Thread.sleep(5000);// 中断线程t// 把标志位false改为truet.interrupt();}
}
我们发现当线程抛出异常时,但线程并没有终止结束。线程里面有个奇怪的设定:如果线程t正在休眠,此时在main中调用interrupt()方法,就能把sleep提前唤醒。InterruptedException支持sleep提前唤醒,通过一场区分sleep是睡足了还是提前醒了。sleep提前唤醒,触发异常之后,然后sleep就会把isInterrupted标志位给重置为false。
之所以会有这样奇怪的设定,是为了给程序员留下更多的操作空间。提前唤醒,可能还存在一些“还未完成的工作”,让程序员自行决定线程t是继续执行、立即结束还是稍等一会结束。上面的代码相当于完全忽视了终止请求。
public class Demo4 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {// 当线程t没有被中断时,打印"hello thread"while (!Thread.currentThread().isInterrupted()) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {// 打印异常调用栈//// e.printStackTrace();// 触发异常就会结束循环,终止线程break;}}});t.start();// 主线程休眠4秒Thread.sleep(5000);// 中断线程t// 把标志位false改为truet.interrupt();}
}
上述几种方式本质上都是线程t自己决定自己是否要终止,相当于main只是给t提供了一个“建议”而不是强制结束。
2.5. 等待一个线程
有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。例如,张三只有等李四转账成功,才决定是否存钱。线程等待,约定了两个线程结束的先后顺序。
哪个线程中调用的join,该线程就是等待的一方;join前面的引用,该线程就是被等的一方。
public class Demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {break;}}});t.start();// 主线程中,可以对线程t进行等待System.out.println("主线程等待之前");// 由于主线程也可能触发阻塞,也可能抛出InterruptedException异常t.join();System.out.println("主线程等待之后");}
}
join这个等待是个死等,只要被等的线程没有结束,join都会始终阻塞。如果上面是个死循环,那么主线程就会永远等待t线程。
上面是t线程等待主线程,也可以让主线程等待t线程。
public class Demo6 {public static void main(String[] args) throws InterruptedException {// 获取主线程Thread mainThread = Thread.currentThread();Thread t = new Thread(() -> {try {System.out.println("t线程等待之前");mainThread.join();System.out.println("t线程等待之后");} catch (InterruptedException e) {e.printStackTrace();}});t.start();// 主线程等待t线程for (int i = 0; i < 10; i++) {System.out.println("hello main");Thread.sleep(1000);}}
}
当然也可以让两个线程同时等待对方,但是这样写代码是意义的,会造成两个线程都无法结束,都无法完成对方的等待操作。
虽然join会触发阻塞,但也不一定会触发,比如在主线程等待t线程之前,t线程已经结束了,此时join就不会阻塞。join默认会是死等,但死等这种情况不太好,如果程序出现了意外,永远等不到结果。所以join方法还有其它的重载版本,可以指定一个最大等待时间(超时时间)。
方法 | 说明 |
join() | 等待线程结束 |
join(long millis) | 等待线程结束,最多等millis毫秒 |
join(long millis,int nanos) | 更高精度 |
public class Demo7 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {break;}}});t.start();System.out.println("等待之前");// 等3秒之后就不等了t.join(3000);System.out.println("等待之后");}
}
2.6. 休眠当前线程
Thread.sleep本质就是让线程的状态变成“阻塞”状态,此线程就不参与CPU调度了。休眠时间到了,线程的状态恢复成就绪状态(不是立即执行),才能参与CPU调度。
相关文章:
JavaEE初阶第四期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(二)
专栏:JavaEE初阶起飞计划 个人主页:手握风云 目录 一、Thread类及常用方法 2.1. Thread的常见构造方法 2.2. Thread的常见属性 2.3. 启动一个线程 2.4. 中断一个线程 2.5. 等待一个线程 2.6. 休眠当前线程 一、Thread类及常用方法 2.1. Thread的…...
Metasploit常用命令详解
一、Metasploit 概述 Metasploit是一款开源的渗透测试框架,由 H.D. Moore 于 2003 年首次发布,目前由 rapid7 公司维护。它整合了大量漏洞利用模块、后渗透工具和漏洞扫描功能,已成为网络安全工程师、红队 / 蓝队成员及安全研究人员的核心工…...
2025.6.24总结
今天发生了两件事,这每件事情都足以影响我的工作状态。 1.团队中有人要转岗 这算是最让我有些小震惊的事件了。我不明白,那个同事干得好好的,为啥会转岗,为啥会被调到其他团队。虽然团队有正编,有od,但我自始自终觉得…...
2023年全国青少年信息素养大赛Python 复赛真题——玩石头游戏
今日python每日练习题为——玩石头游戏,大家记得坚持刷题哦,闯入国赛~ 每轮可拿 1-3 块石头,双方均采取最优策略。若石头数 n 为 4 的倍数,无论先手取 k 块(1≤k≤3),后手总能取 4-k 块…...
MySQL之SQL性能优化策略
MySQL之SQL性能优化策略 一、主键优化策略1.1 主键的核心作用1.2 主键设计原则1.3 主键优化实践 二、ORDER BY优化策略2.1 ORDER BY执行原理2.2 ORDER BY优化技巧2.3 处理大结果集排序 三、GROUP BY优化策略3.1 GROUP BY执行原理3.2 GROUP BY优化方法 四、LIMIT优化策略4.1 LIM…...
AI时代工具:AIGC导航——AI工具集合
大家好!AIGC导航是一个汇集多种AIGC工具的平台,提供了丰富的工具和资源。 工具功能: 该平台整合了多样的AIGC工具,涵盖了绘画创作、写作辅助以及视频制作等多个领域。绘画工具能够生成高质量的图像作品;写作工具支持从构思到润色的全流程写…...
性能测试-jmeter实战4
课程:B站大学 记录软件测试-性能测试学习历程、掌握前端性能测试、后端性能测试、服务端性能测试的你才是一个专业的软件测试工程师 性能测试-jmeter实战4 jmeter环境搭建1. 安装Java环境(必需) JMeter环境搭建完整指南1. 安装Java࿰…...
C++字符串的行输入
1、字符串的输入 下面用一个真实的示例来进行演示: #include<iostream> #include<string>int main() {using namespace std;const int ArSize 20;char name[ArSize];char dessert[ArSize];cout << "Enter your name:\n";cin >>…...
【Linux网络与网络编程】15.DNS与ICMP协议
1. DNS 1.1 DNS介绍 TCP/IP 中使用 IP 地址和端口号来确定网络上的一台主机的一个程序,但是 IP 地址不方便记忆,于是人们发明了一种叫主机名的字符串,并使用 hosts 文件来描述主机名和 IP 地址的关系。最初, 通过互连网信息中心(SRI-NIC)来…...
Python训练营-Day40-训练和测试的规范写法
1.单通道图片训练 # import torch # import torch.nn as nn # import torch.optim as optim # from torchvision import datasets, transforms # from torch.utils.data import DataLoader # import matplotlib.pyplot as plt # import numpy as np# # 设置中文字体支持 # plt…...
【Python-Day 29】万物皆对象:详解 Python 类的定义、实例化与 `__init__` 方法
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
内存泄漏和内存溢出的区别
内存泄漏(Memory Leak)和内存溢出(Memory Overflow / Out Of Memory, OOM)是软件开发中两个密切相关但又本质不同的内存问题: 核心区别一句话概括: 内存泄漏: 有垃圾对象占用内存却无法被回收&…...
Linux系统---Nginx配置nginx状态统计
配置Nignx状态统计 1、下载vts模块 https://github.com/vozlt/nginx-module-vts [rootclient ~]# nginx -s stop [rootclient ~]# ls anaconda-ks.cfg nginx-1.27.3 ceph-release-1-1.el7.noarch.rpm nginx-1.27.3.tar.gz info.sh …...
linux操作系统的软件架构分析
一、linux操作系统的层次结构 1.内核的主要功能 1)进程管理 2)内存管理 3)文件系统 4)进程间通信、I/O系统、网络通信协议等 2.系统程序 1)系统接口函数库,比如libc 2)shell程序 3)编译器、编辑…...
快速手搓一个MCP服务指南(三):FastMCP的核心组件-构建MCP服务的关键技术实现
FastMCP 是一套面向 LLM 应用开发的工具框架,通过标准化协议衔接大语言模型与外部功能组件,构建「LLM工具」的闭环交互体系。其核心技术体系包含四大模块:工具系统将 Python 函数转化为 LLM 可调用的能力单元,通过类型注解实现参数…...
创建首个 Spring Boot 登录项目
📌 摘要 在 Java Web 开发中,登录功能是最基础也是最重要的模块之一。本文将手把手带你使用 IntelliJ IDEA 和 Maven 构建一个基于 Spring Boot 的简单登录系统,涵盖: 使用 IDEA 创建 Spring Boot 项目配置 Maven 依赖ÿ…...
order、sort、distribute和cluster by(Spark/Hive)
1. abstract ORDER BY:完整查询结果的全局行排序。与SORT BY、CLUSTER BY、DISTRIBUTE BY互斥,不能同时使用。 示例SELECT * FROM table_name ORDER BY column_name;SORT BY:只在每个分区内排序,局部排序结果不是全局有序。与ORD…...
# Python中等于号的使用
# Python中等于号的使用 ## 1. 问题的分析与思考 在Python中,等于号()是一个赋值运算符,用于将右侧的值或表达式的结果赋给左侧的变量。这是Python(以及许多其他编程语言)中非常基础且核心的一个概念。理…...
无人机神经网络模块运行与技术难点
一、神经网络模块的运行方式 1. 分层处理架构 感知层 多模态数据融合:通过八元数卷积网络(OCNN)统一处理LiDAR、摄像头、IMU等异构传感器数据,将点云坐标(x/y/z)、图像RGB与光流信息编码至8维虚部&#…...
宝塔服务器调优工具 1.1(Opcache优化)
第一步:宝塔服务器调优工具 1.1(按照下面的参数填写) 第二步:路径/www/server/php/80/etc/php.ini 搜索jit jit1235 其中1235根据服务器情况修改 第三步:路径/www/server/php/80/etc/php-cli.ini 搜索 jit1235 其中…...
day041-web集群架构搭建
文章目录 0. 老男孩思想-高薪四板斧1. web集群架构图2. 搭建异地备份服务2.1 服务端-阿里云服务器2.1.1 查看rsync软件包2.1.2 添加rsync配置文件2.1.3 添加虚拟用户2.1.4 创建校验用户密码文件2.1.5 创建备份目录2.1.6 启动服务2.1.7 开放安全组端口2.1.8 发送检查邮件 2.2 客…...
国产化条码类库Spire.Barcode教程:如何使用 C# 读取 PDF 中的条码(两种方法轻松实现)
在 PDF 文档的 .NET 平台处理流程中,使用 C# 读取 PDF 条码 是一项常见需求,特别适用于处理扫描件或电子表单。无论是物流、金融、医疗还是制造行业,PDF 文档中经常包含用于追踪或识别的条码。这些条码可能是嵌入图像,也可能是矢量…...
vue 3 计算器
效果: <template><div class"calculator-container"><div class"calculator"><!-- 显示区域 --><div class"display">{{ formattedDisplay }}</div><!-- 按钮区域 --><div class"…...
CRMEB PHP多门店版v3.2.1系统全开源+Uniapp前端+搭建教程
一.介绍 CRMEB多店版是一款为品牌连锁门店打造的私域电商解决方案,以三大运营模式为核心,助力品牌连锁门店轻松构建全渠道、一体化的私域电商生态,促进“线上电商”与“线下门店”销售运营融合,加速品牌数字化转型,为…...
主机复制文字和文件到 Ubuntu 虚拟机
在 VMware Workstation Pro 16 中复制文字和文件到 Ubuntu 虚拟机,方法如下: Open-VM-Tools 禁用 Wayland 解决 。 1.安装 VMware Tools(推荐)或 open-vm-tools: sudo apt update sudo apt install open-vm-tools…...
性能测试 —— 数据库的连接池和主从同步和分表分区
一、数据库的调优(库层面) 1、数据库连接池 1、介绍:数据库连接池(Database Connection Pool)是一种用于管理数据库连接的技术,它通过预先创建并维护一组数据库连接来提高应用程序的性能和可扩展性。 2、创建、管理、关闭 数据…...
猿人学js逆向比赛第一届第十二题
一、分析请求 看到这里只有一个m的密文参数,没有cookie,请求头等其他的参数,那么这里跟一堆栈信息。 很顺利地锁定了m的加密位置。看到是字符串拼接然后使用btoa函数进行编码,那么这里尝试使用Python复现一下。顺利拿到结果。 复现…...
第十节 新特性与趋势-CSS层叠规则升级
以下是关于 CSS层叠规则升级 的全面解析,结合最新规范(如级联层layer)和传统层叠机制的演进,从核心原理、应用场景到实践策略的系统性总结: 一、传统层叠规则的三大支柱 CSS层叠规则的传统机制基于以下三个维…...
关键领域软件工厂的安全中枢如何全面升级供应链检测能力
随着软件供应链安全体系在互联网、金融等领域逐步成熟,关键领域正加速迈向以 MLOps、软件工厂为核心的新型研发生态。在这一过程中,面对代码安全、依赖合规、系统可信等多重挑战,传统人工审查模式已难以满足国家级高安全性要求。 Gitee Scan…...
西门子G120XA变频器:数据中心能效革命的核心引擎
在数字经济爆发式增长的今天,数据中心已成为支撑社会运转的"数字心脏"。然而,其庞大的能耗需求与绿色低碳目标之间的矛盾日益凸显——尤其是冷却系统作为数据中心第二大能耗单元(占比约35%),正成为能效提升的…...
从零开始学习Spring Cloud Alibaba (一)
人狠话不多,直接开始少点屁话本着共同学习进步的目的和大家交流如有不对的地方望铁子们多多谅解 准备工具 开发工具 idea Java环境 jdk17 容器: docker Maven 3.8.6 仓库镜像阿里云 <mirror><id>alimaven</id><name>aliyun maven</name><…...
【C/C++】C++ 编程规范:101条规则准则与最佳实践
C 编程规范:101条规则准则与最佳实践 引言 C 是一门强大而复杂的语言,能高效控制硬件,也能写出优雅抽象。然而,正因其复杂性,项目中若缺乏统一规范,极易陷入混乱、难维护、易出错的泥潭。 本文总结了 10…...
PyTorch topk() 用法详解:取最大值
torch.topk(input, k) 返回张量中最大的 k 个元素以及它们在原张量中的 索引。 函数原型 torch.topk(input, k, dimNone, largestTrue, sortedTrue)参数说明: 参数说明input输入张量k要取出的前 k 个值dim指定沿哪个维度取值(默认是最后一维ÿ…...
毕业论文查重原理及降重方法
【30%的重复率有那么重要吗?】 老师说论文重读率必须低于30%,否则无法毕业! 如果您在专科或者普通本科学生,我只能这样一句话告诉你:你想多了~, 真的想多了~~~,一篇论文还不至于让你不能毕…...
Golang Kratos 系列:业务分层的若干思考(二)
上一篇文章简单讨论了领域层在Kratos中的使用,主要涉及引入领域层,将数据层和业务层之间的解耦,接下来讨论一个稍微全面一点的例子,在此基础上引入外部Api(主要是易变部分)的领域层下的情况。 我们同样可以…...
技术伦理之争:OpenAI陷抄袭风波,法院强制下架宣传视频
在AI巨头OpenAI宣布以65亿美元天价收购苹果前设计总监Jony Ive的硬件公司IO仅一个月后,一场抄袭指控将这家科技明星企业推上风口浪尖。 源自谷歌X实验室的初创企业IYO将OpenAI告上法庭,指控其窃取智能耳塞核心技术,并通过巨额收购试图掩盖抄袭…...
烟花爆竹生产企业库房存储安全风险预警系统
烟花爆竹生产企业库房存储安全风险预警系统是保障库房物资安全、规范作业流程、防范安全事故的重要技术手段,涵盖多个关键预警功能。 温湿度预警 在库房内安装温湿度传感器,这些传感器如同敏锐的“环境感知员”,能够实时监测库房内环境变…...
Jenkins+Jmeter+Ant接口持续集成
2025最新Jmeter接口测试从入门到精通(全套项目实战教程) 前言: 为什么要用Jmeter做接口测试: 当选择这套方案的时候,很多人会问,为什么选择Jmeter做Case管理?为什么不自己写框架?说…...
基于STM32的寻迹小车设计
标题:基于STM32的寻迹小车设计 内容:1.摘要 本文围绕基于STM32的寻迹小车设计展开。背景是随着自动化技术的发展,寻迹小车在工业巡检、物流运输等领域有广泛应用前景。目的是设计一款能稳定、准确寻迹的小车。方法上,以STM32微控制器为核心,…...
【150】基于SSM+Vue实现的小说阅读小程序(有文档)
系统介绍 基于SSMVue实现的小说阅读小程序采用前后端分离的架构方式,系统设计了管理员、用户两种角色,系统分为管理端、小程序端,管理端实现了管理员登录、个人中心、管理员管理、帮助中心管理、基础数据管理、论坛中心管理、公告资讯管理、…...
ValKey中使用SIMD指令优化bitcount命令
一、AVX/AVX2 的历史演进 随着计算机技术的飞速发展,数据处理需求呈指数级增长,SIMD(单指令多数据)技术应运而生。它通过一条指令同时处理多个数据元素,大幅提升计算效率,从早期的 MMX 技术起步࿰…...
leetcode114-二叉树展开为链表
leetcode 114 思路 用简单例子推导规律 不要一开始就看复杂的树,先从最简单的情况入手 案例一:只有一个节点 输入:1 输出:1不需要任何操作,直接返回 案例二:有两个节点 输入: 1/2输出&a…...
第七章 习题
1.给出下面表达式的逆波兰表示(后缀式): 3请将表达式-(ab)* (cd)-(abc)分别表示成三元式,间接三元式和四元式序列 四元式(Op,arg1,arg2,result) (,a,b,T1) (,c,d,T2) (*,T1,T2,T3) (uminus,T3,-,T4) (,a,b,T5) (,T5,c,T6) (-,T4,T6,r) 三元式 (op,arg1,arg2) (0) (,…...
Spring Ai Alibaba Graph实现五大工作流模式
Spring Ai Alibaba Graph实现五大工作流模式 概述 在 building-effective-agents 一文中,Anthropic将"智能体系统"(agentic systems),从架构层面分为 “工作流”(workflows)和 “智能体”(agents): 工作流…...
基于单片机的语音控制设计(论文)
摘要 自然语音作为人机交互在目前得以广泛的应用以及极大的发展前景。该设计介绍了基于非指定人语音芯片LD3320的语音控制器结构及其实现语音控制的方法。该语音控制器利用STM32F103C8T6单片机作为主要控制器,控制芯片对输入的进行语音识别并处理,根据语…...
【网络安全】从IP头部看网络通信:IPv4、IPv6与抓包工具 Wireshark 实战
从IP头部看网络通信:IPv4、IPv6与抓包工具 Wireshark实战 在网络安全分析和数据通信的世界中,一切都始于“数据包”。数据包是网络上传输的基本单位,而数据包的结构与内容,正是我们理解网络行为的核心。本文将带你深入了解 IP 协…...
计算机组成原理笔记(公众号版本)
1.MAR,存储单元和PC位数之间的关系 我们的MAR位数取决于我们的存储单元的个数; PC位数也是取决于我们的存储单元的个数; 假设我们是64个存储单元,我们的这个MAR实际上就是6位,因为这个2的6次方等于我们的64吗&#…...
CPM基本原理
CPM(连续相位调制,Continuous Phase Modulation )是一种恒包络,信号相位随时间连续变化的调制技术 。其优势显著,连续相位特性,频谱效率高,对带外辐射抑制好;相位平滑过渡࿰…...
浅谈开源在线客服系统与 APP 集成的技术方案与优劣势
在为移动端 App 接入在线客服系统的过程中,我经历了长时间的技术选型探索。最初,我也曾被一些“技术理想主义”选项所吸引,比如让用户自己研发界面我提供 API 以获得最高自由度,或集成 SDK 以追求原生体验。然而,随着项…...
AutoGPT,自主完成复杂任务
AutoGPT是一个开源的AI Agent项目,它的核心目标是让AI能够自主完成复杂任务,而不仅仅是回答单个问题。简单来说,它让AI具备了"自主思考和行动"的能力。 1. AutoGPT的核心概念 什么是AI Agent? AI Agent(智…...