Java 线程池之FixedThreadPool

引言

在并发编程中,线程池是一种常用的资源管理模式,用于限制并发线程的数量,优化系统性能和资源使用。Java 提供了多种类型的线程池,其中 FixedThreadPool 是一种固定大小的线程池,适用于需要固定数量线程执行任务的场景。本文将详细介绍 FixedThreadPool 的概念、使用场景、配置及示例代码。

什么是 FixedThreadPool

FixedThreadPool 是 Java 并发包(java.util.concurrent)中的一种线程池实现。它创建一个固定数量的线程来处理任务,这些线程将被复用来执行任务,直到线程池被关闭。当所有线程都在忙时,新的任务会被放入一个等待队列中,直到有空闲线程可以执行任务。

创建 FixedThreadPool

使用 Executors 工具类

可以通过 Executors 工具类的工厂方法 newFixedThreadPool 来创建一个固定大小的线程池:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPoolExample {public static void main(String[] args) {ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);for (int i = 0; i < 10; i++) {fixedThreadPool.execute(new Task(i));}fixedThreadPool.shutdown();}
}class Task implements Runnable {private final int taskId;public Task(int taskId) {this.taskId = taskId;}@Overridepublic void run() {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());try {Thread.sleep(2000); // 模拟任务执行时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

自定义线程池配置

除了使用 Executors 工具类,还可以通过 ThreadPoolExecutor 类来自定义配置线程池:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class CustomFixedThreadPoolExample {public static void main(String[] args) {ExecutorService customFixedThreadPool = new ThreadPoolExecutor(4, 4,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());for (int i = 0; i < 10; i++) {customFixedThreadPool.execute(new Task(i));}customFixedThreadPool.shutdown();}
}class Task implements Runnable {private final int taskId;public Task(int taskId) {this.taskId = taskId;}@Overridepublic void run() {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());try {Thread.sleep(2000); // 模拟任务执行时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

工作原理

FixedThreadPool 线程池在创建时会预先启动固定数量的线程,这些线程会在任务提交后执行任务。当所有线程都在执行任务时,新的任务将被放入等待队列,直到有空闲线程可用。线程池会复用这些线程,避免了频繁创建和销毁线程的开销,提高了系统性能和资源利用率。

使用场景

适用于固定数量的并发任务

当应用程序中需要处理的并发任务数量是已知且固定时,FixedThreadPool 是一个理想的选择。它能够控制并发线程的数量,避免过多线程导致的资源耗尽。

适用于长期运行的服务

FixedThreadPool 适用于需要长期运行的服务,例如 Web 服务器或消息处理系统。在这些场景中,固定数量的线程可以提供稳定的性能和响应时间。

注意事项

合理设置线程池大小

设置线程池大小时,应根据系统资源和任务特性进行合理配置。线程池过大可能导致系统资源耗尽,过小则可能导致任务处理速度变慢。可以根据 CPU 核心数和任务的 I/O 特性来设置线程池大小,例如:

  • CPU 密集型任务:线程池大小可以设置为 CPU 核心数 + 1。
  • I/O 密集型任务:线程池大小可以设置为 CPU 核心数的 2 倍或更多。

处理任务队列中的异常

在使用 FixedThreadPool 时,应注意处理任务队列中的异常,以防止线程池中的线程意外终止。例如,可以通过捕获 Runnable 任务中的异常来确保线程继续执行其他任务:

class SafeTask implements Runnable {private final int taskId;public SafeTask(int taskId) {this.taskId = taskId;}@Overridepublic void run() {try {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());Thread.sleep(2000); // 模拟任务执行时间} catch (InterruptedException e) {Thread.currentThread().interrupt();} catch (Exception e) {System.err.println("Task " + taskId + " encountered an error: " + e.getMessage());}}
}

优雅关闭线程池

在使用完线程池后,应调用 shutdown() 方法来优雅地关闭线程池,确保所有已提交的任务都能执行完毕:

fixedThreadPool.shutdown();
try {if (!fixedThreadPool.awaitTermination(60, TimeUnit.SECONDS)) {fixedThreadPool.shutdownNow();}
} catch (InterruptedException e) {fixedThreadPool.shutdownNow();Thread.currentThread().interrupt();
}

结论

FixedThreadPool 是 Java 并发包中一种常用的线程池实现,适用于固定数量并发任务的场景。通过合理配置线程池大小和任务队列处理,可以有效提高系统的性能和资源利用率。理解并正确使用 FixedThreadPool,可以帮助开发者编写高效且稳定的并发程序。

希望本文能帮助你理解 FixedThreadPool 的基本概念及其使用方法。如果你有任何问题或建议,欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/40334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序 npm 支持

使用 npm 包 目前小程序已经支持使用 npm 安装第三方包&#xff0c;因为 node_modules 目录中的包不会参与小程序项目的编译、 上传和打包&#xff0c;因此在小程序 项目中要使用的 npm 包&#xff0c;必须走一遍构建 npm 的过程。在构建成功以后&#xff0c;默认 会在小程序目…

【keil5问题】keil5中突然debug调试不能全速运行的问题

1、问题现象&#xff1a; 原本的项目工程是正常debug单步调试&#xff0c;然后突然出现是点击左上角的run全速运行&#xff0c;也全速运行不了&#xff0c;出现如下图的情况&#xff0c;点一次一步走的现象 2、问题解决&#xff1a; 2-1、问题分析&#xff1a; 点击reset、…

关于pytorch的加载数据,cpu init, cpu getitem, gpu init

文章目录 一. (cpu,init)图像加载到CPU内存&#xff0c;是在 __init__中函数中全部数据, 然后在item中取图像二.(cpu,get_item)是图像在 get_item函数中&#xff0c;载入图像到CPU三(gpu,init)是将图像加载到GPU, 在init函数中 跑多光谱估计的代码&#xff0c;参考&#xff1a;…

如何使用 uni-app 快速集成聊天会话能力?

移动互联网时代&#xff0c;即时通讯&#xff08;IM&#xff09;功能是许多app不可或缺的一部分&#xff0c;然而在即时通讯app开发时&#xff0c;开发者常常面临着选择困难&#xff1a;是为每个平台单独开发应用&#xff0c;还是有限开发某个平台&#xff1f;uni-app的出现&am…

BLOB视频技术原理,如何将Blob视频转换为MP4格式?

BLOB视频的制作涉及将视频数据转换为二进制大对象&#xff08;BLOB&#xff09;格式&#xff0c;然后对其进行编码、分割、封装和传输。在目标设备上&#xff0c;BLOB数据被解析、解码和播放&#xff0c;同时可能需要进行实时的优化以适应播放条件。这种制作方式旨在提供一种高…

linux监控服务器磁盘、内存空间使用率到达90%发送邮件脚本

以下是一个使用Python编写的Linux监控服务器磁盘、内存空间使用率并在达到90%时发送邮件的脚本&#xff1a; import os import smtplib from email.mime.text import MIMEText from email.header import Header# 设置阈值 DISK_THRESHOLD 90 MEMORY_THRESHOLD 90# 获取磁盘使…

7月11日云技术研讨会 | 车载信息安全全流程实施方案

伴随着汽车的智能网联化发展&#xff0c;网络攻击也逐渐渗透漫延至汽车领域&#xff0c;汽车行业面临着重大的信息安全挑战。此外&#xff0c;UNECE WP.29 R155和ISO/SAE 21434等标准也对汽车的信息安全提出了规范化要求&#xff0c;旨在分阶段将产品全生命周期中由信息安全威胁…

中介子方程四十二

XXFXXuXXWXXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXuXXrXXaXnXXαXLXyXXWXuXeXuXWXXyXLXαXXnXaXXrXXuXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXKXηXiXXnXXyXηXuXXrXXaXnXXαXLXyXXWXuXeXuXWXXyXLXαXXnXaXXrXXuXηXyXXnXXiXηXKXXpXuXXα…

JavaScript中的this指向

1. 全局环境下的this 在全局环境中&#xff08;在浏览器中是window对象&#xff0c;在Node.js中是global对象&#xff09;&#xff0c;this指向全局对象。 console.log(this window); // 在浏览器中为true console.log(this.document ! undefined); // true&#xff0c;因为…

opencv编译报错OpenCV does not recognize MSVC_VERSION “1940“

具体如下: CMake Warning at cmake/OpenCVDetectCXXCompiler.cmake:182 (message):OpenCV does not recognize MSVC_VERSION "1940". Cannot set OpenCV_RUNTIME Call Stack (most recent call first):CMakeLists.txt:174 (include) 打开源码\opencv\sources\cmak…

如何加密U盘?U盘加密软件推荐

U盘是我们最常用的移动存储设备&#xff0c;可以帮助我们随身携带大量数据。为了避免U盘数据泄露&#xff0c;我们需要加密保护U盘。那么&#xff0c;U盘该如何加密呢&#xff1f;下面小编就为大家推荐两款专业的U盘加密软件。 U盘超级加密3000 U盘超级加密3000是一款优秀的U盘…

大模型概述-定义/分类/训练/应用

大模型概述 随着时代的发展, 大模型各个领域的应用正在不断扩大. 本文尽力梳理各种材料, 将从概念定义, 类型分类, 训练以及应用等方面对大模型进行一个简要的概述. 如果你想了解大模型但是却缺乏基础的知识或者觉得无从下手, 那么阅读该文章可能对你有所帮助. 如果想了解更多…

react antd表格翻页时记录勾选状态

在Ant Design的React表格&#xff08;Table&#xff09;组件中&#xff0c;如果需要在翻页时记住勾选状态&#xff0c;可以通过以下步骤实现&#xff1a; 使用rowSelection属性来控制勾选状态&#xff0c;并添加preserveSelectedRowKeys: true以保留 key。 设置rowKey属性。 …

Django任意URL跳转漏洞(CVE-2018-14574)

目录 Django介绍 URL跳转漏洞介绍 Django任意URL跳转漏洞介绍 环境搭建 防御方法 前段时间在面试时&#xff0c;问到了URL跳转漏洞&#xff0c;我没有回答好&#xff0c;下午把URL跳转漏洞学习了&#xff0c;发现也不难&#xff0c;看来还需要学习的东西很多呀&#xff0c…

cadence symbol修改之一

cdaence virtuoso 复制cell&#xff0c;或者拷贝symbol之后&#xff0c;再次调用的时候&#xff0c;symbol还是跟随原来的cell名字 解决办法 打开对应的symbol 修改partName为 cellName

把前端打包放到Eladmin框架中运行

再resuorces目录创建static文件夹&#xff0c;然后把前端文件放进来 然后修改 ConfigurerAdapter文件&#xff0c;如下图所示 这样就可以通过ip端口/index.html 这样访问啦&#xff01;

基于Lua源码开发动态库供lua脚本使用

通过require的方式可以加载动态库&#xff0c;然后脚本就可以使用库中提供的函数&#xff0c;一般过程如下&#xff1a; 比如有一个动态库名为&#xff1a;MyFirstLua.dll 则使用时&#xff1a;MyFirstLua require("MyFirstLua") 导出的函数接口名称一定是 int l…

垂直领域大模型的机遇与挑战:从构建到应用

在人工智能技术的浪潮中,大模型以其强大的数据处理和学习能力,成为推动科技进步的重要力量。然而,这种跨领域应用的过程并非一帆风顺,既面临挑战也蕴含机遇。本文从复旦大学的研究工作出发,详细分析大模型的机遇与挑战。 背景 GPT4技术报告指出,GPT4仍处于通用人工智…

Mybatis连接数据库

文章目录 大纲定义类、创建表添加相关依赖五件套5.1 mybatis-config.xml5.2 MybatisUtils.java5.3 \**Mapper.xml5.4 \**Mapper.java5.5 \**Dao.java 测试类 大纲 在Java中定义类、在数据库汇总创建表添加依赖编写5件套测试 定义类、创建表 import java.time.LocalDate; imp…

土壤分析仪:分析土壤中的各种养分

土壤作为地球生命的摇篮&#xff0c;承载着农作物的生长与繁衍。土壤中的养分是农作物生长的关键。 一、土壤分析仪的工作原理 土壤分析仪是一种采用先进传感技术的仪器设备&#xff0c;能够精确测量土壤中的PH值、电导率、有机质含量、养分含量以及微生物数量等参数。它利用多…