四种线程池的创建及任务提交
1. 线程池概述
1.1 线程池的定义
线程池是管理和控制线程使用的一种手段。它通过提前创建一定数量的线程,并将任务提交给这些线程执行,来实现资源的合理分配和任务的高效处理。
关键点:
- 线程复用:线程池在任务执行完毕后,不会销毁线程,而是让线程继续等待下一个任务。
- 任务调度:线程池可以通过队列对任务进行排序和分发,确保资源合理利用。
- 统一管理:线程池对线程的创建、销毁、调度进行统一管理,避免资源浪费。
1.2 为什么使用线程池?
使用线程池可以带来以下好处:
-
避免频繁创建销毁线程的开销
- 每次创建线程需要分配资源,如内存堆栈、CPU 调度等,销毁线程也需要一定的代价。
- 线程池通过线程复用机制,减少了这种频繁操作的系统开销。
-
限制并发数量,防止系统过载
- 无限制地创建线程可能导致系统资源耗尽,甚至引发宕机。
- 线程池通过设置最大线程数量,合理控制并发任务数。
-
提高任务响应速度
- 线程池中的线程是提前创建好的,当有新任务时可以立即分配线程执行,而无需等待线程创建。
-
统一管理任务队列和线程生命周期
- 线程池可以管理任务的执行顺序,提供优先级支持,并统一处理线程的生命周期。
1.3 线程池的工作原理
线程池的基本工作流程如下:
-
任务提交:
- 用户将任务提交给线程池,任务可以是实现了
Runnable
或Callable
接口的对象。 - 线程池会将任务放入任务队列中等待执行。
- 用户将任务提交给线程池,任务可以是实现了
-
线程分配:
- 如果线程池中有空闲线程,则立即分配线程执行任务。
- 如果没有空闲线程,且线程池未达到最大线程数,则创建新线程来处理任务。
- 如果线程数已达上限,任务会进入等待队列,直到有空闲线程可用。
-
任务执行:
- 被分配的线程从任务队列中取出任务,调用
run()
或call()
方法来执行任务逻辑。
- 被分配的线程从任务队列中取出任务,调用
-
线程回收:
- 任务执行完毕后,线程不会被销毁,而是返回线程池等待下一次任务分配。
- 如果线程长时间空闲且超出线程池的核心线程数限制,线程会被销毁以节约资源。
工作原理图:
任务提交 → 加入任务队列 → 分配线程 → 任务执行 → 线程回收
1.4 线程池的核心参数
线程池的行为主要由以下核心参数控制:
-
核心线程数(corePoolSize):
- 线程池中始终保持的线程数量,即使线程处于空闲状态也不会回收。
- 适合设置为系统平均负载的并发数量。
-
最大线程数(maximumPoolSize):
- 线程池中允许创建的最大线程数量,控制资源消耗的上限。
-
任务队列(workQueue):
- 用于保存待执行任务的队列类型,如
ArrayBlockingQueue
或LinkedBlockingQueue
。
- 用于保存待执行任务的队列类型,如
-
线程存活时间(keepAliveTime):
- 超过核心线程数的线程在空闲状态下能存活的时间,适用于动态调整线程池规模。
-
线程工厂(ThreadFactory):
- 定制线程的创建方式,如线程命名、优先级设置等。
-
任务拒绝策略(RejectedExecutionHandler):
- 当线程池及其队列都满了时,如何处理新提交的任务:
AbortPolicy
:直接抛出异常(默认策略)。CallerRunsPolicy
:由提交任务的线程自己执行任务。DiscardPolicy
:直接丢弃任务,不抛异常。DiscardOldestPolicy
:丢弃队列中最老的任务。
- 当线程池及其队列都满了时,如何处理新提交的任务:
2. 提交任务的方法
线程池的任务提交方式主要分为以下两种,分别对应不同的应用场景和返回值需求。
2.1 提交方式一:execute()
方法
execute()
是线程池的基本任务提交方法,适用于不需要任务执行结果的场景。
方法定义:
void execute(Runnable command)
工作原理:
- 将任务提交到线程池。
- 如果线程池中有空闲线程,立即执行任务。
- 如果没有空闲线程,任务将被放入任务队列。
- 如果队列已满且线程数已达最大值,则触发拒绝策略。
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecuteExample {public static void main(String[] args) {// 创建一个固定大小为3的线程池ExecutorService executorService = Executors.newFixedThreadPool(3);// 提交任务for (int i = 1; i <= 5; i++) {int taskId = i;executorService.execute(() -> {System.out.println("任务 " + taskId + " 正在执行,线程:" + Thread.currentThread().getName());try {Thread.sleep(1000); // 模拟任务耗时} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("任务 " + taskId + " 执行完毕");});}// 关闭线程池executorService.shutdown();}
}
输出示例:
任务 1 正在执行,线程:pool-1-thread-1
任务 2 正在执行,线程:pool-1-thread-2
任务 3 正在执行,线程:pool-1-thread-3
任务 1 执行完毕
任务 4 正在执行,线程:pool-1-thread-1
任务 2 执行完毕
...
优点:
- 简单快捷。
- 适合不需要返回值的任务。
注意:
- 无法直接获取任务的执行结果。
- 如果任务中抛出异常,可能无法感知。
2.2 提交方式二:submit()
方法
submit()
方法更灵活,可以用来提交 Runnable
或 Callable
任务,并返回一个 Future
对象,以便在后续获取任务执行结果。
方法定义:
<T> Future<T> submit(Callable<T> task)
Future<?> submit(Runnable task)
工作原理:
- 将任务提交到线程池。
- 任务执行后,结果会存储在
Future
对象中。 - 可以通过
Future
的get()
方法获取结果,或在任务未完成时进行阻塞等待。
示例代码:
import java.util.concurrent.*;public class SubmitExample {public static void main(String[] args) throws InterruptedException, ExecutionException {// 创建一个固定大小为2的线程池ExecutorService executorService = Executors.newFixedThreadPool(2);// 提交 Runnable 任务Future<?> runnableFuture = executorService.submit(() -> {System.out.println("Runnable 任务正在执行,线程:" + Thread.currentThread().getName());});// 提交 Callable 任务Future<String> callableFuture = executorService.submit(() -> {System.out.println("Callable 任务正在执行,线程:" + Thread.currentThread().getName());return "任务结果";});// 等待任务完成并获取结果System.out.println("Callable 任务的返回值:" + callableFuture.get());// 关闭线程池executorService.shutdown();}
}
输出示例:
Runnable 任务正在执行,线程:pool-1-thread-1
Callable 任务正在执行,线程:pool-1-thread-2
Callable 任务的返回值:任务结果
优点:
- 支持返回结果(适用于
Callable
)。 - 可以通过
Future
检测任务完成状态或取消任务。
注意:
get()
方法会阻塞当前线程,直到任务完成。- 如果任务抛出异常,
Future.get()
会抛出ExecutionException
。
2.3 两种提交方法的对比
特性 | execute() | submit() |
---|---|---|
任务类型 | 仅支持 Runnable | 支持 Runnable 和 Callable |
返回值 | 无返回值 | 返回 Future ,可获取结果或检查状态 |
任务抛出异常的处理方式 | 可能被忽略 | 通过 Future.get() 抛出异常 |
使用场景 | 不关心任务结果的简单任务 | 需要获取任务结果或处理异常的场景 |
小结:
execute()
是基础的任务提交方式,适合无结果任务。submit()
更灵活,适合需要结果或异常处理的任务。
3. 四种线程池的创建
Java 提供了 Executors
工具类,用于快速创建常见类型的线程池。这些线程池类型根据不同的需求场景设计,可以有效管理线程的创建和回收。
3.1 创建方式一:固定大小线程池(FixedThreadPool)
特点:
- 拥有固定数量的线程。
- 无论有多少任务,线程池中的线程数量始终保持不变。
- 任务超出线程数量时,将进入任务队列等待执行。
适用场景:
- 稳定且长期运行的任务,线程数量可根据系统资源确定。
创建方式:
ExecutorService executorService = Executors.newFixedThreadPool(int nThreads);
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPoolExample {public static void main(String[] args) {// 创建固定大小为3的线程池ExecutorService executorService = Executors.newFixedThreadPool(3);// 提交5个任务for (int i = 1; i <= 5; i++) {int taskId = i;executorService.execute(() -> {System.out.println("任务 " + taskId + " 正在执行,线程:" + Thread.currentThread().getName());try {Thread.sleep(1000); // 模拟任务耗时} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}// 关闭线程池executorService.shutdown();}
}
运行效果: 固定数量的线程执行任务,其余任务在队列中等待:
任务 1 正在执行,线程:pool-1-thread-1
任务 2 正在执行,线程:pool-1-thread-2
任务 3 正在执行,线程:pool-1-thread-3
任务 4 等待执行
任务 5 等待执行
3.2 创建方式二:单线程线程池(SingleThreadExecutor)
特点:
- 只有一个线程在执行任务。
- 所有任务会按照提交的顺序(FIFO,先进先出)执行。
- 适合需要顺序执行任务的场景。
适用场景:
- 确保任务按顺序执行。
- 不需要并发操作时,例如日志记录。
创建方式:
ExecutorService executorService = Executors.newSingleThreadExecutor();
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class SingleThreadExecutorExample {public static void main(String[] args) {// 创建单线程线程池ExecutorService executorService = Executors.newSingleThreadExecutor();// 提交3个任务for (int i = 1; i <= 3; i++) {int taskId = i;executorService.execute(() -> {System.out.println("任务 " + taskId + " 正在执行,线程:" + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}// 关闭线程池executorService.shutdown();}
}
运行效果: 任务严格按顺序执行:
任务 1 正在执行,线程:pool-1-thread-1
任务 2 正在执行,线程:pool-1-thread-1
任务 3 正在执行,线程:pool-1-thread-1
3.3 创建方式三:缓存线程池(CachedThreadPool)
特点:
- 线程数量不固定,动态调整。
- 如果有空闲线程可用,则复用空闲线程;如果没有空闲线程,则创建新线程。
- 空闲线程超过 60 秒未使用会被销毁。
适用场景:
- 大量短期任务,且任务数量不确定。
创建方式:
ExecutorService executorService = Executors.newCachedThreadPool();
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class CachedThreadPoolExample {public static void main(String[] args) {// 创建缓存线程池ExecutorService executorService = Executors.newCachedThreadPool();// 提交10个任务for (int i = 1; i <= 10; i++) {int taskId = i;executorService.execute(() -> {System.out.println("任务 " + taskId + " 正在执行,线程:" + Thread.currentThread().getName());});}// 关闭线程池executorService.shutdown();}
}
运行效果: 任务数量多时,会快速创建新线程:
任务 1 正在执行,线程:pool-1-thread-1
任务 2 正在执行,线程:pool-1-thread-2
...
任务 10 正在执行,线程:pool-1-thread-10
3.4 创建方式四:定时线程池(ScheduledThreadPool)
特点:
- 用于执行定时任务或周期性任务。
- 可以延迟执行任务或按照固定时间间隔循环执行任务。
适用场景:
- 周期性任务调度,例如定时备份、定时发送邮件。
创建方式:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(int corePoolSize);
示例代码:
import java.util.concurrent.*;public class ScheduledThreadPoolExample {public static void main(String[] args) {// 创建定时线程池ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);// 延迟3秒执行任务scheduledExecutorService.schedule(() -> {System.out.println("延迟执行任务,线程:" + Thread.currentThread().getName());}, 3, TimeUnit.SECONDS);// 每2秒执行一次任务scheduledExecutorService.scheduleAtFixedRate(() -> {System.out.println("周期性任务,线程:" + Thread.currentThread().getName());}, 1, 2, TimeUnit.SECONDS);}
}
运行效果:
- 延迟 3 秒后执行一次任务。
- 每 2 秒执行一次周期性任务。
小结
类型 | 特点 | 适用场景 |
---|---|---|
FixedThreadPool | 固定线程数量,任务超出进入队列 | 稳定并发任务 |
SingleThreadExecutor | 单线程,顺序执行任务 | 需要任务严格按顺序执行的场景 |
CachedThreadPool | 线程数量动态调整 | 短期、大量任务,任务数不确定 |
ScheduledThreadPool | 支持定时和周期性任务 | 定时任务和循环任务 |
相关文章:
四种线程池的创建及任务提交
1. 线程池概述 1.1 线程池的定义 线程池是管理和控制线程使用的一种手段。它通过提前创建一定数量的线程,并将任务提交给这些线程执行,来实现资源的合理分配和任务的高效处理。 关键点: 线程复用:线程池在任务执行完毕后&#…...
【优选算法】查找总价格为目标值的两个商品
链接:LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode) 解法:利用单调性,使用双指针算法解决问题 1.先从小到大排序 2. sum > t : right--; sum < t : left; sum t : return class Solution {public…...
从零开始学架构——互联网架构的演进
1 技术演进 1.1 技术演进的动力 对于新技术,我们应该站在行业的角度上思考,哪些技术我们要采取,哪些技术我们不能用,投入成本过大会不会导致满盘皆输?市场、技术、管理三者组成的业务发展铁三角,任何一个…...
Linux 系统常见问题
SSH问题 SSH连接服务器时报错: ssh_exchange_identification: read: Connection reset by peer 报错信息: ssh_exchange_identification: read: Connection reset by peer可以通过ssh -p root -v查看连接时详情 解决方法: vi /etc/host…...
工厂模式与抽象工厂模式在Unity中的实际应用案例
一、实验目的 实践工厂模式和抽象工厂模式的实际应用。 创建一个小型的游戏场景,通过应用这些设计模式提升游戏的趣味性和可扩展性。 掌握在复杂场景中管理和使用不同类型的对象。 比较在实际游戏开发中不同设计模式的实际效果和应用场景。 学习如何进行简单的性…...
AI定义汽车/跨域融合/整车智能,汽车智能化2.0时代新机会来了
汽车智能化2.0,产业正在发生深度变革。 一方面,AI大模型开始在多个域同步赋能智能汽车,从智能座舱到智能驾驶,再到底盘域,AI大模型正在快速推动汽车变革为超级智能体,AI定义汽车时代开始来临。 另一方面&…...
QT----------多媒体
实现思路 多媒体模块功能概述: QT 的多媒体模块提供了丰富的功能,包括音频播放、录制、视频播放和摄像头操作等。 播放音频: 使用 QMediaPlayer 播放完整的音频文件。使用 QSoundEffect 播放简短的音效文件。 录制音频: 使用 QMe…...
[ubuntu-22.04]ubuntu不识别rtl8153 usb转网口
问题描述 ubuntu22.04插入rtl8153 usb转网口不识别 解决方案 安装依赖包 sudo apt-get install libelf-dev build-essential linux-headers-uname -r sudo apt-get install gcc-12 下载源码 Realtek USB FE / GBE / 2.5G / 5G Ethernet Family Controller Softwarehttps:/…...
洛谷P1525 [NOIP2010 提高组] 关押罪犯(种子并查集基础)
题目链接:P1525 [NOIP2010 提高组] 关押罪犯 - 洛谷 | 计算机科学教育新生态 题目难度:普及+/提高 题目描述: S 城现有两座监狱,一共关押着 N 名罪犯,编号分别为 1∼N,有m对罪犯,每对之间有仇恨值,问如何分配罪犯使得现 Z 市长要看到其中最大的矛盾值最小。 输入格…...
Android笔试面试题AI答之Android基础(11)
Android入门请看《Android应用开发项目式教程》,视频、源码、答疑,手把手教 文章目录 1.Android的权限有哪些?**1. 普通权限****常见普通权限** **2. 危险权限****权限分组****常见危险权限组及权限** **3. 特殊权限****常见特殊权限** **4. …...
【智行安全】基于Synaptics SL1680的AI疲劳驾驶检测方案
随著车载技术的快速进步,驾驶安全越来越受到重视,而疲劳驾驶是造成交通事故的重要原因之一。传统的驾驶监控技术因精度不足或反应迟缓,无法满足实时监测需求。因此,结合人工智能技术的疲劳驾驶检测系统成为行业新方向,…...
多分类的损失函数
在多分类任务中,常用的损失函数能够衡量模型输出的类别分布与目标类别之间的差异,帮助模型学习更准确的分类能力。以下是多分类任务中常用的损失函数: 1. 交叉熵损失(Cross-Entropy Loss) 公式: CrossEntropyLoss = − 1 N ∑ i =...
探索数据之美,Plotly引领可视化新风尚
在数据如潮的今天,如何精准捕捉信息的脉搏,让数据说话?Plotly,这款强大的数据可视化工具,正以其卓越的性能和丰富的功能,成为数据分析师、科学家及工程师们的得力助手。 Plotly不仅仅是一个绘图库…...
青少年编程与数学 02-006 前端开发框架VUE 02课题、创建工程
青少年编程与数学 02-006 前端开发框架VUE 02课题、创建工程 一、开发环境(一)WebStorm安装WebStorm配置WebStorm安装中文语言包安装 Translation插件 (二)Node.jsWindows系统安装Node.jsLinux系统安装Node.jsNode.js与Vue.js的关…...
高并发场景下的秒杀系统架构设计与实现
引言 秒杀系统是一种高并发场景的典型应用,广泛存在于电商平台、抢票系统和促销活动中。秒杀活动的特点是短时间内吸引大量用户同时访问并尝试抢购商品,这对系统的高并发处理能力、稳定性和用户体验提出了极高的要求。 在秒杀系统中,常见的…...
局域网中单台交换机VLAN应用
网络拓扑 其中交换机接口类型都为access接口。 Ethernet 0/0/1 VLAN ID为10 Ethernet 0/0/2 VLAN ID为10 Ethernet 0/0/5 VLAN ID为20 Ethernet 0/0/6 VLAN ID为20 Host-1 ip为192.168.64.11/24 Host-2 ip为192.168.64.12/24 Host-3 ip为192.168.64.21/24 Host-4 ip为192.168…...
UNI-APP_i18n国际化引入
官方文档:https://uniapp.dcloud.net.cn/tutorial/i18n.html vue2中使用 1. 新建文件 locale/index.js import en from ./en.json import zhHans from ./zh-Hans.json import zhHant from ./zh-Hant.json const messages {en,zh-Hans: zhHans,zh-Hant: zhHant }…...
纯血鸿蒙ArkUI选项卡布局详解
当页面信息较多的时候,为了让用户能够聚焦于当前显示的内容,需要对页面的内容进行分类,提高页面空间利用率。Tabs组件可以在一个页面内实现快速的视图内容切换,一方面提升查找信息的效率,另一方面精简用户单词获取到的…...
从0开始的opencv之旅(1)cv::Mat的使用
目录 Mat 存储方法 创建一个指定像素方式的图像。 尽管我们完全可以把cv::Mat当作一个黑盒,但是笔者的建议是仍然要深入理解和学习cv::Mat自身的构造逻辑和存储原理,这样在查找问题,或者是遇到一些奇奇怪怪的图像显示问题的时候能够快速的想…...
uniapp 微信小程序开发使用高德地图、腾讯地图
一、高德地图 1.注册高德地图开放平台账号 (1)创建应用 这个key 第3步骤,配置到项目中locationGps.js 2.下载高德地图微信小程序插件 (1)下载地址 高德地图API | 微信小程序插件 (2)引入项目…...
Activation Functions
Chapter4:Activation Functions 声明:本篇博客笔记来源于《Neural Networks from scratch in Python》,作者的youtube 其实关于神经网络的入门博主已经写过几篇了,这里就不再赘述,附上链接。 1.一文窥见神经网络 2.神经…...
【TextIn—智能文档解析与DocFlow票据AI自动化处理:赋能企业文档数字化管理与数据治理的双重利器】
TextIn—智能文档解析与票据AI自动化处理:赋能企业文档数字化管理与数据治理的双重利器 在数据驱动的时代,企业面临的挑战不仅在于海量数据的整理和响应速度的提高,更在于如何有效管理和利用这些日益增长的海量信息。尤其是在信息日趋多样…...
Quartus In-System Sources and Probes Editor 的使用说明
文章目录 前言使用说明参考资料 前言 Quartus 提供了 In-System Sources and Probes Editor 调试工具,通过 JTAG 接口使用该工具可以驱动和采样内部节点的逻辑值。即通过 Sources 功能来驱动 FPGA 内部信号,通过 Probes 功能来探测内部节点的逻辑值。在…...
【视觉SLAM:八、后端Ⅱ】
视觉SLAM后端的核心任务是估计相机的轨迹和场景的三维结构,这需要解决非线性优化问题。为了保证效率和精度,后端主要依赖以下两种方法:滑动窗口法(基于局部优化的策略)和位姿图优化(基于全局优化的策略&…...
【大模型实战篇】LLaMA Factory微调ChatGLM-4-9B模型
1. 背景介绍 虽然现在大模型微调的文章很多,但纸上得来终觉浅,大模型微调的体感还是需要自己亲自上手实操过,才能有一些自己的感悟和直觉。这次我们选择使用llama_factory来微调chatglm-4-9B大模型。 之前微调我们是用两块3090GPU显卡&…...
多个DataV遍历生成
DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…...
【JavaWeb后端学习笔记】MySQL的常用函数(字符串函数,数值函数,日期函数,流程函数)
MySQL函数 1、字符串函数2、数值函数3、日期函数4、流程函数 1、字符串函数 函数说明concat(s1, s2, …, sn)字符串拼接,将 s1, s2, …, sn 拼接成一个字符串lower(str)将字符串 str 全部转为小写upper(str)将字符串 str 全部转为大写lpad(str, n, pad)左填充&…...
开源AI智能名片2+1链动模式O2O商城小程序在流量留存与转化中的深度应用与优化策略
摘要 在数字化时代,企业面临的市场竞争日益激烈,传统的营销手段已难以满足当前市场的多样化需求。开源AI智能名片21链动模式O2O商城小程序作为一种创新的数字化营销工具,凭借其开源特性、AI智能名片功能、21链动模式以及O2O商城小程序的优势…...
API多并发识别、C#文字识别
在当今数字化转型的浪潮中,信息处理的速度和准确性成为了企业在市场中立足的关键因素之一。特别是在大数据时代,海量的信息需要被快速、精确的解析和利用,因此,这正是文字识别技术大放异彩的舞台。翔云平台针对市场需求࿰…...
JVM和异常
Java 虚拟机(Java Virtual Machine,简称 JVM) 概述 JVM 是运行 Java 字节码的虚拟计算机,它是 Java 程序能够实现 “一次编写,到处运行(Write Once, Run Anywhere)” 特性的关键所在。Java 程…...
设计模式 创建型 单例模式(Singleton Pattern)与 常见技术框架应用 解析
单例模式(Singleton Pattern)是一种创建型设计模式,旨在确保某个类在应用程序的生命周期内只有一个实例,并提供一个全局访问点来获取该实例。这种设计模式在需要控制资源访问、避免频繁创建和销毁对象的场景中尤为有用。 一、核心…...
idea( 2022.3.2)打包报错总结
一 报错 class lombok.javac.apt.LombokProcessor (in unnamed module 0x4fe64d23) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing …...
基于SpringBoot在线竞拍平台系统功能实现十一
## 一、前言介绍:1.1 项目摘要 随着网络技术的飞速发展和电子商务的普及,竞拍系统作为一种新型的在线交易方式,已经逐渐深入到人们的日常生活中。传统的拍卖活动需要耗费大量的人力、物力和时间,从组织拍卖、宣传、报名、竞拍到成…...
kubernetes学习-Service
kubernetes学习-Service 1. Service说明2. 功能3.Service类型3.1 NodePort3.1.1 创建web-service.yaml3.1.2 创建web-pod.yaml3.1.3 部署3.1.4 验证 3.2 ClusterIP3.2.1 创建web-clusterIp-service.yaml3.2.2 创建web-clusterIp-pod.yaml3.2.3 部署3.2.4 验证 3.3 LoadBalancer…...
【bluedroid】A2dp Source播放流程源码分析(4)
接上集分析:【bluedroid】A2dp Source播放流程源码分析(3)-CSDN博客 蓝牙和AUDIO之间的接口 蓝牙和audio之间的通信是通过socket,管理socket中的文件是UIPC,UIPC管理两条socket。 A2DP_CTRL_PATH /data/misc/bluedroid/.a2dp_ctrl A2DP_DATA_PATH /data/misc/bluedroid…...
vue3基础,小白从入门到精通
目录 一、vue.js 简述 二、 下载 vue.esm-browser.js 这个模块文件 三、创建第一个Vue程序 3.1创建代码过程 四、v-on 五、循环遍历(v-for) 六、判断语法(v-if和v-show) 6.1节点的动态属性v-bind 6.2 用v-bind实现CSS样式绑定 一、vue.js 简述 Vue 3 是一款流行的 J…...
Go 如何优雅退出进程
优雅退出设计步骤 在 Go 项目中,设计优雅退出(Graceful Shutdown)时,通常需要确保在收到退出信号时,程序能够安全地清理资源并优雅地退出。以下是常见的优雅退出设计步骤: 步骤 1:创建 contex…...
#Vue3篇: 无感刷新token的原理JSESSIONID无感刷新和JWT接口刷新
基于这个后端是怎么更新token的 为了理解后端是如何更新 Token 的,我们需要考虑一个典型的基于 Token 的身份验证流程,特别是涉及 JSESSIONID 和自定义 Token(如 JWT, JSON Web Token)的情况。 下面我将介绍两种常见的更新 Token …...
从零开始学桶排序:Java 示例与优化建议
目录 一、桶排序的工作原理 二、适用场景 三、桶排序的时间复杂度 四、Java 实现桶排序 桶排序(Bucket Sort)是一种基于分桶的排序算法,适用于输入数据分布较均匀的场景。它通过将元素分配到不同的“桶”中,然后对每个桶内的元…...
自定义luacheck校验规则
安装运行环境 安装环境及源码解析,参考:LuaCheck校验原理解析 自定义校验规则 从代码中可以看出,定义一条规则有以下关键点: 需要定义告警信息:由键值对组成,key为告警编码(不一定为纯数字&…...
Mac连接云服务器工具推荐
文章目录 前言步骤1. 下载2. 安装3. 常用插件安装4. 连接ssh测试5. 连接sftp测试注意:ssh和sftp的区别注意:不同文件传输的区别解决SSL自动退出 前言 Royal TSX是什么: Royal TSX 是一款跨平台的远程桌面和连接管理工具,专为 mac…...
【react】Redux的设计思想与工作原理
Redux 的设计理念 Redux 的设计采用了 Facebook 提出的 Flux 数据处理理念 在 Flux 中通过建立一个公共集中数据仓库 Store 进行管理,整体分成四个部分即: View (视图层)、Action (动作)、Dispatcher (派发器)、Stor…...
深入解析Android JNI:以Visualizer为例
深入解析Android JNI:以Visualizer为例 引言 Java Native Interface (JNI) 是Java平台提供的一种机制,允许Java代码与本地代码(如C/C++)进行交互。在Android开发中,JNI被广泛用于性能优化、访问底层系统API、以及复用现有的C/C++库。本文将通过Android中的Visualizer类,…...
Java基于SpringBoot的甘肃非物质文化网站的设计与实现,附源码
博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...
Unity小白工作心得(无限记录)
24届毕业,11月才找到工作在一家小公司。工作两个月了,遇到最大的问题就是探索新知识,每天都是摸索式前进,因为工作面临着交付,你不得不想尽办法解决问题然后交给上面,但其他程序员用的引擎不一样࿰…...
STC单片机内部常见寄存器及其作用
STC单片机内部常见寄存器及其作用 STC单片机是基于8051架构的增强型单片机,广泛应用于嵌入式系统中。其内部有多个特殊功能寄存器(SFR, Special Function Register),用于控制硬件模块(如定时器、串口、中断等…...
【亚马逊云】基于Amazon EC2实例部署 NextCloud 云网盘并使用 Docker-compose 搭建 ONLYOFFICE 企业在线办公应用软件
文章目录 1. 部署EC2实例2. 安装 Docker 服务3. 安装docker-compose4. 创建Docker-compose文件5. 创建nginx.conf文件6. 运行docker-compose命令开始部署7. 访问ONLYOFFICE插件8. 访问NextCloud云盘9. 下载并启用ONLYOFFICE插件10. 上传文件测试11. 所遇问题12. 参考链接 1. 部…...
vim、watch、cp和mv
一、vim使用技巧 vim主配置文件:/etc/vimrc (对所有用户都生效) vim子配置文件:vim ~/.vimrc (只对当前用户生效) 可写入: set nu 显示行号 ts2 tab键长度为两个空格(默认为8个空格…...
【Linux】:线程安全 + 死锁问题
📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 1. 线程安全和重入问题&…...
HarmonyOS Next 应用元服务开发-应用接续动态配置迁移保持迁移连续性
保证迁移连续性,由于迁移加载时,目标端拉起的应用可能执行过自己的迁移状态设置命令(如:冷启动时目标端在onCreate中设置了INACTIVE;热启动时对端已打开了不可迁移的页面,迁移状态为INACTIVE等情况…...