ExecutorService详解:Java 17线程池管理从零到一
简介
在现代高并发应用中,线程池管理已成为提升系统性能与稳定性的关键核心技术。ExecutorService作为Java并发编程的核心接口,提供了对线程池的强大抽象与管理能力,相比直接管理线程,它能显著降低资源消耗、提高响应速度并增强系统可维护性。随着Java 17的发布,线程池管理能力得到了进一步强化,支持更灵活的动态参数调整策略。本文将从零到一全面解析ExecutorService接口的核心概念、线程池类型选择、参数配置方法、开发实践及企业级应用,帮助开发者构建高效稳定的线程池管理方案。
一、线程池核心概念与优势
线程池是一种预先创建并复用线程的机制,它能够有效解决传统线程管理的痛点。传统线程管理需要为每个任务创建独立线程,这会导致频繁的资源分配与回收,不仅增加系统开销,还可能引发线程泄漏和资源竞争问题。而线程池通过维护一个线程池,将任务提交到池中,由池内的线程负责执行,从而避免了这些问题。
ExecutorService作为Java中管理线程池的高级接口,提供了对异步任务的统一抽象。其核心优势包括:
- 资源管理:通过限制线程数量,防止系统资源过度消耗。例如,当任务队列已满且线程池达到最大线程数时,会触发拒绝策略而非无限创建线程。
- 任务队列缓冲:通过阻塞队列机制,将任务进行缓冲,避免任务被丢弃或处理不及时。
- 错误处理:提供统一的异常捕获与处理机制,而非依赖每个线程的独立错误处理。
- 扩展能力:支持定时任务、周期任务等多样化场景,并可通过继承实现自定义行为。
在线程池中,任务队列扮演着"缓冲带"的角色,当线程池中的线程都处于忙碌状态时,新任务会被暂时放入队列中等待执行。根据队列类型的不同,线程池会采取不同的任务调度策略,这也是线程池参数配置的关键所在。
二、线程池类型与参数配置
Java线程池主要通过ThreadPoolExecutor类实现,而Executors工厂类提供了几种常见的预定义线程池类型。不同类型的线程池适用于不同场景,开发者需根据任务特性进行合理选择:
1. FixedThreadPool
FixedThreadPool是一个固定大小的线程池,适用于任务量稳定的场景。其参数配置为:核心线程数等于最大线程数,且使用无界队列(默认为LinkedBlockingQueue)。这意味着:
- 当线程数达到核心线程数时,新任务会被放入队列中等待
- 队列容量理论上无限,但实际使用中可能因内存限制而溢出
- 适合任务量固定的场景,但无法应对突发流量
示例代码:
ExecutorService executorService = Executors.newFixedThreadPool(5);
2. CachedThreadPool
CachedThreadPool是一个动态调整大小的线程池,适用于短期任务场景。其参数配置为:
- 核心线程数为0
- 最大线程数为Integer.MAX_VALUE
- 使用SynchronousQueue作为任务队列
- 空闲线程存活时间为1分钟
这意味着新任务会优先尝试由空闲线程处理,若无空闲线程则创建新线程,但新线程在空闲超过1分钟后会被回收。这种配置非常适合处理大量短暂任务的场景,如网络请求处理,但需注意避免长时间运行的任务,否则可能导致线程数量激增。
3. SingleThreadExecutor
SingleThreadExecutor是一个单线程的线程池,保证任务按顺序执行。其参数配置为:
- 核心线程数为1
- 最大线程数为1
- 使用无界队列(默认为LinkedBlockingQueue)
这种线程池适用于需要严格保证任务执行顺序的场景,如处理事务性操作或需要保持状态一致性的任务。通过SingleThreadExecutor,开发者可以确保任务的执行顺序与提交顺序完全一致。
4. ScheduledThreadPool
ScheduledThreadPool支持定时任务和周期性任务执行,是处理定时任务的理想选择。其参数配置与ThreadPoolExecutor类似,但额外支持调度方法:
- schedule():安排任务在指定延迟后执行一次
- scheduleAtFixedRate():安排任务在初始延迟后以固定频率重复执行
- scheduleWithFixedDelay():安排任务在初始延迟后以固定延迟重复执行
在实际应用中,ScheduledThreadPool通常与手动配置的ThreadPoolExecutor结合使用,以获得更灵活的控制。
三、线程池参数详解与配置策略
ThreadPoolExecutor作为线程池的实际实现类,提供了七大核心参数供开发者配置。合理的参数配置直接影响线程池的性能表现和系统的稳定性,需要根据任务类型(CPU密集型或IO密集型)和系统资源进行针对性设置。
1. 核心参数详解
参数 | 类型 | 说明 | 默认值 |
---|---|---|---|
corePoolSize | int | 线程池保持的核心线程数 | 1 |
maximumPoolSize | int | 线程池允许的最大线程数 | Integer.MAX_VALUE |
keepAliveTime | long | 非核心线程空闲后的存活时间 | 60秒 |
unit | TimeUnit | keepAliveTime的时间单位 | TimeUnit.SECONDS |
workQueue | BlockingQueue | 任务队列,用于缓存等待执行的任务 | SynchronousQueue |
threadFactory | ThreadFactory | 创建新线程的工厂 | Executors.defaultThreadFactory() |
rejectedExecutionHandler | RejectedExecutionHandler | 任务被拒绝时的处理策略 | ThreadPoolExecutor.AbortPolicy |
在企业级应用中,建议手动创建ThreadPoolExecutor实例而非依赖Executors工厂方法,以避免默认的无界队列带来的内存溢出风险。
2. 队列类型选择指南
任务队列是线程池的核心组件,直接影响任务调度和系统稳定性。不同类型的队列适用于不同场景,选择合适的队列类型是线程池配置的关键:
队列类型 | 特点 | 适用场景 |
---|---|---|
SynchronousQueue | 无容量,任务必须立即被线程消费 | CPU密集型任务,需最小化任务等待时间 |
LinkedBlockingQueue | 基于链表的无界或有界队列 | 任务量波动较大的场景,需设置明确容量 |
ArrayBlockingQueue | 基于数组的有界队列 | 需要精确控制任务积压数量的场景 |
DelayedWorkQueue | 优先级队列,保证延迟任务按顺序执行 | 定时任务调度 |
对于高并发系统,推荐使用有界队列(如ArrayBlockingQueue)并设置合理的容量。根据任务类型的不同,容量设置也有差异:IO密集型任务可设置较大的队列容量(如100-500),而CPU密集型任务则应较小(如10-50)。
3. 线程池大小计算公式
线程池的大小设置直接影响系统性能。根据任务特性和系统资源,可采用以下计算公式:
- CPU密集型任务:线程数 = CPU核心数 + 1
- IO密集型任务:线程数 = CPU核心数 × 2
实际应用中,可先根据公式设置核心线程数,再根据压测结果调整最大线程数。例如,对于8核CPU的服务器,可设置:
- IO密集型线程池:corePoolSize=16,maximumPoolSize=32
- CPU密集型线程池:corePoolSize=9,maximumPoolSize=18
四、线程池创建与任务提交
1. 线程池创建步骤
在Java 17中,创建线程池可通过ThreadPoolExecutor的构造方法实现,支持动态参数调整。手动创建线程池比使用Executors工厂方法更灵活,且能避免无界队列的风险:
// 1. 自定义线程工厂
ThreadFactory customThreadFactory = new CustomThreadFactory("MyThreadPoolThread");// 2. 创建有界队列
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);// 3. 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, // 核心线程数20, // 最大线程数60, // 空闲线程存活时间TimeUnit.SECONDS,workQueue, // 任务队列customThreadFactory, // 线程工厂new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
自定义线程工厂有助于监控和管理线程池中的线程,可记录线程创建时间、设置线程名称前缀等。
2. 任务提交方法对比
线程池提供了多种任务提交方法,各有特点:
- execute(Runnable command):提交一个不返回结果的任务,无返回值
- submit(Runnable task):提交一个Runnable任务,返回Future对象,可用于异步检查任务状态
- submit(Callable task):提交一个返回结果的任务,返回Future对象,可用于获取执行结果
- invokeAll(Collection<? extends Callable> tasks):提交一组任务,等待所有任务完成并返回结果列表
- invokeAny(Collection<? extends Callable> tasks):提交一组任务,等待其中任一任务完成并返回结果
submit()方法相比execute()方法的优势在于返回Future对象,允许开发者获取任务执行结果或检查任务状态。在实际应用中,推荐优先使用submit()方法,特别是需要处理任务结果或需要异常捕获的场景。
3. 任务执行流程
线程池处理任务的过程可概括为以下步骤:
- 提交任务到线程池
- 如果线程数未达到核心线程数,创建新线程执行任务
- 如果线程数已达到核心线程数,将任务加入队列等待
- 如果队列已满且线程数未达到最大线程数,创建新线程执行任务
- 如果队列已满且线程数已达到最大线程数,触发拒绝策略
这个执行流程可用Mermaid语法绘制为可视化流程图,帮助理解线程池的工作原理:
相关文章:
ExecutorService详解:Java 17线程池管理从零到一
简介 在现代高并发应用中,线程池管理已成为提升系统性能与稳定性的关键核心技术。ExecutorService作为Java并发编程的核心接口,提供了对线程池的强大抽象与管理能力,相比直接管理线程,它能显著降低资源消耗、提高响应速度并增强系统可维护性。随着Java 17的发布,线程池管…...
Go 中闭包的常见使用场景
在 Go 中,闭包(Closure) 是一个函数值,它引用了其定义时所在作用域中的变量。也就是说,闭包可以访问并修改外部作用域中的变量。 Go 中闭包的常见使用场景 ✅ 1. 封装状态(无须结构体) 闭包可…...
养生:打造健康生活的四大支柱
饮食养生:吃对食物,滋养生命根基 饮食是健康的物质基础,需遵循 “均衡、天然、顺应时节” 原则: 三餐科学搭配: 早餐以高蛋白 膳食纤维为主,如燕麦粥配水煮蛋、蓝莓,快速激活代谢;…...
OpenCV 图像直方图:从原理剖析到实战应用
在数字图像处理领域,图像直方图是一种强大而基础的工具,它以直观的方式展示了图像中像素值的分布情况。OpenCV 作为广泛应用的计算机视觉库,提供了丰富的函数来处理图像直方图。本文将深入讲解图像直方图的原理、OpenCV 中的实现方法…...
springboot+vue实现在线书店(图书商城)系统
今天教大家如何设计一个图书商城 , 基于目前主流的技术:前端vue,后端springboot。 同时还带来的项目的部署教程。 视频演示 在线书城 图片演示 一. 系统概述 商城是一款比较庞大的系统,需要有商品中心,库存中心,订单…...
LLM Text2SQL NL2SQL 实战总结
目录 尽量全面的描述表的功能 尽量全面的描述字段的功能 适当放弃意义等价的字段 放弃业务上无用的字段 对于LLM来说,由于它没有什么行业经验,所以我们需要尽可能的给予它恰当的“背景信息”,才能使它更好的工作。所谓恰当,不是越多越好,因为太多的信息会消耗掉LLM的可…...
SQLPub:一个提供AI助手的免费MySQL数据库服务
给大家介绍一个免费的 MySQL 在线数据库环境:SQLPub。它提供了最新版本的 MySQL 服务器测试服务,可以方便开发者和测试人员验证数据库功能,也可以用于学习 MySQL。 免费申请 在浏览器中输入以下网址: https://sqlpub.com/ SQLP…...
EasyExcel集成使用总结与完整示例
EasyExcel集成使用总结与完整示例 一、EasyExcel简介 EasyExcel是阿里巴巴开源的Java库,专注于简化Excel文件的读写操作。它基于Apache POI进行了优化,采用流式处理,具有低内存占用和高性能的特点,非常适合处理大规模数据的导入…...
【hot100-动态规划-139.单词拆分】
力扣139.单词拆分 本题要求判断给定的字符串 s 是否可以被空格拆分为一个或多个在字典 wordDict 中出现的单词,且不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用,这是一个典型的动态规划问题。 动态规划思路 定义状态: 定义一个布尔类型的数组 dp,其中…...
人工神经网络(ANN)模型
一、概述 人工神经网络(Artificial Neural Network,ANN),是一种模拟生物神经网络结构和功能的计算模型,它通过大量的神经元相互连接,实现对复杂数据的处理和模式识别。从本质上讲,人工神经网络是…...
2025ICPC陕西省赛题解
L. easy 每行选能选的最小的两个,注意处理奇数的情况。 #include <bits/stdc.h> #define x first #define y second #define int long longusing namespace std; typedef unsigned long long ULL ; typedef pair<int,int> PII ; typedef pair<lon…...
不同进制的数据展示(十进制、十六进制、编码方式)
目录 1、十六进制的数值转为十进制(可能是补码) 2、十进制转为十六进制(负数要转为补码) 背景: (1) 接收到通讯的数据,把数据读取出来,并转成自己想要的格式。 &#x…...
贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现
贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现 目录 贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现效果一览基本介绍程序设计参考资料…...
为什么doris是实时的?
Apache Doris 作为实时分析型数据库的核心竞争力源于其技术架构与功能设计的深度融合,以下从关键特性解析其实时能力的技术实现: 一、 MPP架构驱动分布式并行计算 基于 大规模并行处理(MPP)架构,Dori…...
ProceedingJoinPoint的认识
ProceedingJoinPoint 是 Spring AOP(面向切面编程) 中的核心接口,用于在 环绕通知(Around) 中拦截方法调用并控制其执行流程。以下是对其功能和用法的详细解释: 核心作用 拦截目标方法 在方法执行前后插…...
穿透工具如何保证信息安全?
引言 在当今数字化时代,网络穿透工具(如VPN、SSH隧道、内网穿透工具等)已成为企业远程办公和个人隐私保护的重要技术手段。然而,这些工具本身也可能成为信息安全的风险点。本文将探讨穿透工具如何在不牺牲便利性的前提下ÿ…...
卷积神经网络和深度神经网络的区别是什么?
近 6000 字长文梳理深度神经网络结构。 先来一个省流版回答:卷积神经网络(CNN)只是深度神经网络(DNN)家族中的一员,其处理数据(如图像)的核心方式是卷积操作,因此而得名…...
C#语言中 (元,组) 的发展史
C# 中的元组(Tuple)详解 元组(Tuple)是 C# 中的一种数据结构,用于将多个不同类型的值组合成一个复合值。元组在 C# 7.0 中得到了重大改进,提供了更简洁的语法和更好的性能。 1. 元组的基本概念 元组允许你将多个值组合成一个单…...
Apollo学习——planning模块(3)之planning_base
planning_component、planning_base、on_lane_planning 和 navi_planning 的关系 1. 模块关系总览 继承层次 PlanningComponent:Cyber RT 框架中的 入口组件,负责调度规划模块的输入输出和管理生命周期。PlanningBase:规划算法的 抽象基类&…...
【SPIN】PROMELA语言编程入门基础语法(SPIN学习系列--1)
PROMELA(Protocol Meta Language)是一种用于描述和验证并发系统的形式化建模语言,主要与SPIN(Simple Promela Interpreter)模型检查器配合使用。本教程将基于JSPIN(SPIN的Java图形化版本)&#…...
Linux --systemctl损坏
systemctlSegmentation fault (core dumped) 提示这个 Ubuntu/Debian sudo apt-get update sudo apt-get --reinstall install systemdCentOS/RHEL sudo yum reinstall systemd # 或 CentOS 8 / RHEL 8 sudo dnf reinstall systemd...
Vue3+ElementPlus 开箱即用后台管理系统,支持白天黑夜主题切换,通用管理组件,
Vue3ElementPlus后台管理系统,支持白天黑夜主题切换,专为教育管理场景设计。主要功能包括用户管理(管理员、教师、学生)、课件资源管理(课件列表、下载中心)和数据统计(使用情况、教学效率等&am…...
Seata源码—3.全局事务注解扫描器的初始化二
大纲 1.全局事务注解扫描器继承的父类与实现的接口 2.全局事务注解扫描器的核心变量 3.Spring容器初始化后初始化Seata客户端的源码 4.TM全局事务管理器客户端初始化的源码 5.TM组件的Netty网络通信客户端初始化源码 6.Seata框架的SPI动态扩展机制源码 7.向Seata客户端注…...
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七)
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七) 在 Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(六)-CSDN博客 的基础上改进,主要是…...
快速搭建一个electron-vite项目
1. 初始化项目 在命令行中运行以下命令 npm create quick-start/electronlatest也可以通过附加命令行选项直接指定项目名称和你想要使用的模版。例如,要构建一个 Electron Vue 项目,运行: # npm 7,需要添加额外的 --: npm cre…...
Python网络请求利器:urllib库深度解析
一、urllib库概述 urllib是Python内置的HTTP请求库,无需额外安装即可使用。它由四个核心模块构成: urllib.request:发起HTTP请求的核心模块urllib.error:处理请求异常(如404、超时等)…...
2025认证杯第二阶段数学建模B题:谣言在社交网络上的传播思路+模型+代码
2025认证杯数学建模第二阶段思路模型代码,详细内容见文末名片 一、引言 在当今数字化时代,社交网络已然成为人们生活中不可或缺的一部分。信息在社交网络上的传播速度犹如闪电,瞬间就能触及大量用户。然而,这也为谣言的滋生和扩…...
IP地址、端口、TCP介绍、socket介绍、程序中socket管理
1、IP地址:IP 地址就是 标识网络中设备的一个地址,好比现实生活中的家庭地址。IP 地址的作用是 标识网络中唯一的一台设备的,也就是说通过IP地址能够找到网络中某台设备。 2、端口:代表不同的进程,如下图: 3、socket:…...
leetcode0621. 任务调度器-medium
1 题目:任务调度器 官方标定难度:中 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表,用字母 A 到 Z 表示,以及一个冷却时间 n。每个周期或时间间隔允许完成一项任务。任务可以按任何顺序完成,但有一个限制…...
中小型培训机构都用什么教务管理系统?
在教育培训行业快速发展的今天,中小型培训机构面临着学员管理复杂、课程体系多样化、教学效果难以量化等挑战。一个高效的教务管理系统已成为机构运营的核心支撑。本文将深入分析当前市场上适用于中小型培训机构的教务管理系统,重点介绍爱耕云这一专业解…...
centos7 基于yolov10的推理程序环境搭建
这篇文章的前提是系统显卡驱动已经安装 安装步骤参照前一篇文章centos7安装NVIDIA显卡 安装Anaconda 下载地址anaconda.com 需要注册账号获取下载地址 wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh赋予权限 chmod ax Anaconda3-2024.10-1-…...
Web GIS可视化地图框架Leaflet、OpenLayers、Mapbox、Cesium、ArcGis for JavaScript
Mapbox、OpenLayers、Leaflet、ArcGIS for JavaScript和Cesium是五种常用的Web GIS地图框架,它们各有优缺点,适用于不同的场景。还有常见的3d库和高德地图、百度地图。 1. Mapbox 官网Mapbox Gl JS案列:https://docs.mapbox.com/mapbox-gl-…...
Kafka如何实现高性能
Kafka如何实现高性能 Kafka之所以能成为高性能消息系统的标杆,是通过多层次的架构设计和优化实现的。 一、存储层优化 1. 顺序I/O设计 日志结构存储:所有消息追加写入,避免磁盘随机写分段日志:将日志分为多个Segment文件&…...
如何通过partclone克隆Ubuntu 22系统
如何通过partclone克隆Ubuntu 22系统 一. 背景知识:为什么要克隆系统?二. 准备工作详解2.1 选择工具:为什么是partclone?2.2 制作定制化ISO的深层原因 三. 详细操作步骤3.1 环境准备阶段3.2 ISO改造关键步骤3.3 启动到Live环境3.4…...
语义化路径是什么意思,举例说明
下面的java代码输出结果是/a/b/../c/./a.txt/a/c/a.txt,语义化路径是什么意思呢?代码如下所示: import org.springframework.util.StringUtils; public class StringUtilsTest { /** 字符串处理 */ Test public void …...
Dockerfile构建镜像
Dockerfile 构建镜像 # 使用本地已下载的 java:8-alpine 镜像作为基础镜像 FROM java:8-alpine# 设置工作目录 WORKDIR /home/www/shop# 复制 JAR 文件到容器中 COPY ./fkshop-build.jar /home/www/shop/fkshop-build.jar# 复制配置文件(如果需要) COPY…...
vue3.0的name属性插件——vite-plugin-vue-setup-extend
安装 这个由于是在开发环境下的一个插件 帮助我们支持name属性 所以需要是-D npm i vite-plugin-vue-setup-extend -D在pasckjson中无法注释每个插件的用处 可以在vscode中下载一个JsonComments这样可以在json中添加注释方便日后维护和查阅API 引入 在vite.config.js中 im…...
gRPC为什么高性能
gRPC 之所以具备高性能的特性,主要得益于其底层设计中的多项关键技术优化。以下从协议、序列化、传输机制、并发模型等方面详细解析其高性能的原因: 1. 基于 HTTP/2 协议的核心优势 HTTP/2 是 gRPC 的传输基础,相较于 HTTP/1.x,它通过以下机制显著提升了效率: 多路复用(…...
进度管理高分论文
2022年,xx县开展紧密型县域医共体建设,将全县县、镇两级医疗机构组建成2家医共体,要求医共体内部实行行政、人员、财务、业务、信息、绩效、药械“七统一”管理。但是卫生系统整体信息化水平较低,业务系统互不相通,运营…...
每日算法刷题计划Day7 5.15:leetcode滑动窗口4道题,用时1h
一.定长滑动窗口 【套路】教你解决定长滑窗!适用于所有定长滑窗题目! 模版套路 1.题目描述 1.计算所有长度恰好为 k 的子串中,最多可以包含多少个元音字母 2.找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。 3.…...
C++核心编程--1 内存分区模型
C程序执行时,内存可以划分为4部分 代码区:存放函数体的二进制代码 全局区:存放全局变量、静态变量、常量 栈区:局部变量、函数参数值,编译器自动分配和释放 堆区:程序员自己分配和释放 1.1 程序运行前…...
产品更新丨谷云科技 iPaaS 集成平台 V7.5 版本发布
五月,谷云科技 iPaaS 集成平台保持月度更新, V7.5 版本于近日正式发布。我们一起来看看新版本有哪些升级和优化。 核心新增功能:深化API治理,释放连接价值 API网关:全链路可控,精准管控业务状态 业务状态…...
【AI论文】对抗性后期训练快速文本到音频生成
摘要:文本到音频系统虽然性能不断提高,但在推理时速度很慢,因此对于许多创意应用来说,它们的延迟是不切实际的。 我们提出了对抗相对对比(ARC)后训练,这是第一个不基于蒸馏的扩散/流模型的对抗加…...
欧拉计划 Project Euler 73(分数有范围计数)题解
欧拉计划 Project Euler 73 题解 题干分数有范围计数 思路code 题干 分数有范围计数 考虑形如 n d \frac{n}{d} dn的分数,其中 n n n和 d d d均为正整数。如果 n < d n<d n<d且其最大公约数为1,则称该分数为最简真分数。 将所有 d ≤ 8 d\l…...
Quic如何实现udp可靠传输
QUIC(Quick UDP Internet Connections)是由 Google 设计并被 IETF 标准化的传输层协议,它基于 UDP 实现,但提供了类似 TCP 的可靠性和更高级的功能(如多路复用、0-RTT 握手、TLS 加密等)。 尽管 UDP 是不可…...
本地文件操作 MCP (多通道处理) 使用案例
## 概述 文件操作 MCP (Multi-Channel Processing) 是一种用于高效处理本地文件的框架和库,它提供了并行处理、批量操作、监控和异常处理等功能。通过多通道架构,MCP 能够显著提高大规模文件操作的效率,特别适用于需要处理大量文件或大型文件…...
Blender 入门教程(三):骨骼绑定
一、前言 不知道大家有没有玩过一些单机游戏的 Mod,比如《侠盗猎车》里主角变成奥特曼,各种新能源汽车乱入等等。 这些都是别人对原有模型就行修改换皮,并重新绑定骨骼完成的,所以如果会了骨骼绑定后,你也就可以自己…...
Java 异常处理之 BufferOverflowException(BufferOverflowException 概述、常见发生场景、避免策略)
一、BufferOverflowException 概述 BufferOverflowException 是 Java NIO 包中的一个运行时异常,是 RuntimeException 的子类 public class BufferOverflowException extends RuntimeException {... }# 继承关系java.lang.Object-> java.lang.Throwable-> j…...
密码学实验:凯撒密码
密码学实验:凯撒密码 一、实验目的 掌握凯撒密码的数学原理:理解字符移位与模运算的结合,实现加解密算法。理解暴力破解本质:通过穷举有限密钥空间,掌握利用语言特征破解密文的方法。编程实践:用Python实…...
C40-指针
一 指针的引入 什么是指针:指针是一个变量,其值是另一个变量的内存地址 简单的使用地址输出一个变量: 代码示例 #include <stdio.h> int main() {int a10;printf("a的地址是:%p\n",&a);printf("a%d\n",*(&a)); //*号是取值运算符…...