Java并发必杀技!线程池让你的程序速度飙升不止一点点!

embedded/2024/10/21 3:36:17/

在这里插入图片描述

文章目录

    • 1 线程池的工作机制是什么?
    • 2 线程池的任务出现异常该怎么解决?
    • 3 线程池的内存泄露该如何解决?

近期迷上了举例子来结合知识点学习,尽量减少枯燥,如有错见谅哈~

1 线程池的工作机制是什么?

线程池的工作机制是管理和重用线程,以提高多任务处理的效率和性能。

想象一下,线程池就像是一支备战的队伍,提前准备了一些士兵(线程),他们随时待命。

当有任务(任务是需要完成的工作)到达时,如果有空闲的士兵,任务就会分配给他们去执行。

如果所有的士兵都在忙,任务就会暂时排队等待,直到有士兵空闲下来为止。执行完任务后,士兵不会立刻解散,而是等待下一个任务的到来继续服务,这样可以节省时间和精力。

创建线程池初期,会预先准备一些线程,这些线程待命着,准备接受任务。

任务到达线程池时,线程池会检查当前活跃的线程数和任务队列的状态。

如果有空闲线程,线程池会将任务分配给其中一个空闲线程执行。

如果所有线程都在忙碌中,任务会被暂时存储在一个任务队列中,等待有空闲线程时再取出执行。

执行任务的过程中,线程池会处理线程的创建、重用和管理。

任务执行完毕后,线程不会被立即销毁,而是保留在池中,以备下次任务到来时重复利用。

这种重复利用减少了线程创建和销毁的开销,提升了系统的响应速度和资源利用率。

额外扩展:线程池还能根据配置自动调整线程数量,比如固定大小线程池有固定数量的线程,而缓存线程池则根据需要动态调整线程数量。

2 线程池的任务出现异常该怎么解决?

当线程池中的任务出现异常时,通常需要采取一些措施来处理和避免影响整个系统的稳定性和运行。

想象一下,线程池中的士兵(线程)执行任务时,如果遇到了问题,比如任务出现了异常,就像是士兵在执行任务时遭遇了意外。

线程池会立即捕捉到这个异常情况,然后会有一名指挥官(异常处理器)负责接收并处理这个异常信息。

指挥官可能会通知其他队员(开发人员),并采取相应的措施,比如记录战报(写入日志)、调集救援队(发送警报)等,以便及时修复任务中的问题,并确保队伍继续高效运行。

线程池会捕获任务执行过程中抛出的异常。

方法一:

如果设置了异常处理器(ExceptionHandler),它会接收到异常信息,并可以进行特定的处理,比如记录日志、发送警报等操作,以便开发人员能够及时了解并调试问题。

方法二:

线程池会尝试终止出问题的线程,并将这个线程从池中移除,同时创建一个新的线程来取代它,确保整体运行不受影响。

代码Demo:

java">ExecutorService executor = Executors.newFixedThreadPool(5);// 提交任务到线程池
executor.submit(() -> {try {// 执行任务代码// 可能会抛出异常的代码} catch (Exception e) {// 异常处理逻辑System.err.println("任务执行出现异常:" + e.getMessage());// 记录日志或发送警报等}
});// 关闭线程池
executor.shutdown();

3 线程池的内存泄露该如何解决?

线程池就像是一个工厂,负责执行一系列的任务。内存泄露就好比是工厂里的某个地方出现了漏水,导致水无法被正确排出去。

在线程池中,如果任务执行过程中出现内存泄露 ,就意味着某些任务执行时使用的内存没有被及时释放,会导致系统资源的浪费和性能下降 。

原因:

任务中使用了大量的内存或者一些资源没有被及时清理。

解决方案:

方案一:

需要详细检查每个任务的代码,确保在任务执行完毕后释放掉所有的资源。比如,如果任务中使用了大对象或者打开了文件、数据库连接等资源,就要在任务执行完成后,显式地关闭这些资源,这样可以确保资源能够被及时释放,避免内存堆积问题。

方案二:

考虑调整线程池的配置,比如调整线程池的大小,避免创建过多的线程,以减少内存占用。合理配置线程池参数可以有效地控制资源的使用,提高系统的稳定性和性能。

代码Demo:

java">ExecutorService executor = Executors.newFixedThreadPool(10);// 提交任务到线程池
executor.submit(() -> {try {// 执行任务代码,可能会引起内存泄露的操作// 比如创建大对象或者打开资源} finally {// 确保在任务执行结束后,释放资源// 比如关闭文件、数据库连接等}
});// 关闭线程池
executor.shutdown();

确保在任务执行完毕后,无论是否发生异常,都会执行资源释放的操作,这有助于避免内存泄露问题的发生。

面对挫折,选择成长而非逃避,因为磨砺使人锋利


http://www.ppmy.cn/embedded/97466.html

相关文章

搭建内网开发环境(二)|Nexus安装及使用

引言 上一篇教程中按照了 docker 作为容器化工具,在本篇教程中将使用 docker-compose 安装 nexus。 搭建内网开发环境(一)|基于docker快速部署开发环境 什么是 Nexus Nexus是一个强大的仓库管理器,主要用于搭建和管…

算法力扣刷题记录 八十七【53. 最大子序和】

前言 贪心章节第4篇。动态规划章节第10篇。同一题,两种方法。 记录 八十七【53. 最大子序和】 一、题目阅读 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 …

JavaEE 第9节 阻塞队列详解

一、概念 阻塞队列是在普通队列(先进先出的数据结构)的基础上增加了阻塞属性的特殊队列 1)当阻塞队列空的时候,如果继续出队元素会进入阻塞状态,直到其他线程入队元素。 2)当阻塞队列满的时候,…

[000-01-030].Zookeeper学习大纲

我的博客大纲 我的后端学习大纲 第一步:Zookeeper是什么 1.第01节:Zookeeper概述 第二步:Zookeeper怎么使用: 2.1.开发环境搭建 2.第02节 :Zookeeper本地安装3.第03节 :Zookeeper集群操作 2.2.具体使用…

企业级批量无人值守安装

企业级批量无人值守安装 一、批量无人值守安装1.简介PXE工作流程 2.核心技术(dhcp、httpd、tftp)3.实验3.1 准备环境3.2 防护关闭3.3 软件安装3.4 软件配置DHCP服务设置httpd服务配置tftp服务配置 3.5 编写引导安装相关文件,放到指定位置3.5.…

【漫谈C语言和嵌入式013】函数指针与指针函数详解:概念、区别及实例

在C语言中,理解指针的各种用法是非常关键的,特别是当涉及到更复杂的概念如函数指针和指针函数时。这两者听起来非常相似,但实际上是完全不同的概念。在这篇博客中,我们将探讨函数指针和指针函数的定义、区别以及如何在实际中使用它…

共享经济背景下校园、办公闲置物品交易平台-计算机毕设Java|springboot实战项目

🍊作者:计算机毕设匠心工作室 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目…

yolov8语义分割训练-验证-推理-转化-数据集(代码+教程)

实例分割概述 实例分割是计算机视觉任务的一种,它超越了简单的物体检测,能够识别图像中的单个物体并将其从图像的其余部分分割出来。这种高级别的分割技术不仅能定位物体的位置,还能精确描绘出每个物体的实际形状。 实例分割模型的输出 实…