java线程池详解
在Java中,线程池是一种重要的多线程处理方式,通过管理和复用线程,提高应用程序的性能和响应速度,减少线程创建和销毁的开销,避免线程数量过多导致系统负载过高的问题。本文将详细介绍Java线程池的概念、核心参数、工作流程、常见类型、拒绝策略以及使用方法和优化建议。
一、线程池的概念
线程池就是线程的池子,用来管理和复用线程。它可以在应用程序中有效地管理线程的生命周期、调度和执行。线程池包含一组预先创建的线程,这些线程可以被动态分配给执行任务,从而避免了不断创建和销毁线程的开销。线程池通常用于执行大量的异步任务,提高多线程程序的性能和稳定性。
二、线程池的核心参数
线程池的核心参数包括:
- corePoolSize(核心线程数):线程池中保持的最小线程数,即使线程是空闲的。这些线程在处理任务时不会被回收,除非设置了allowCoreThreadTimeOut(true)来允许核心线程在空闲时被回收。
- maximumPoolSize(最大线程数):线程池允许的最大线程数,包括核心线程和非核心线程。当任务队列已满且活动线程数小于最大线程数时,会创建新的线程。
- keepAliveTime(线程空闲时间):非核心线程的空闲时间超过这个值就会被回收。指定非核心线程空闲线程的最长存活时间。
- unit(时间单位):用于指定keepAliveTime的时间单位,可以是TimeUnit.MILLISECONDS等。
- workQueue(任务队列):用于保存等待执行的任务。选择合适的任务队列,例如LinkedBlockingQueue、ArrayBlockingQueue等,以满足需求。
- threadFactory(线程工厂):用于创建新线程。通过线程工厂可以给每个创建出来的线程设置更有意义的名字。
- handler(拒绝策略):当队列和线程池都满了,说明线程池处于饱和状态,必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。还可以选择CallerRunsPolicy(用调用者所在线程来运行任务)、DiscardPolicy(丢弃队列里最近的一个任务,并执行当前任务)、DiscardOldestPolicy(丢弃最老的任务,尝试重新提交新的任务)等策略,或者根据应用场景实现RejectedExecutionHandler接口自定义策略。
三、线程池的工作流程
线程池的工作流程如下:
- 当有新任务来时,将先使用核心线程执行。
- 当任务数达到核心线程数时,后续的任务会被放入任务队列中等待执行。
- 如果任务队列已满,且活动线程数小于最大线程数,会创建新的非核心线程来执行任务。
- 当任务数达到最大线程数时,线程池满了,如果有新的任务,将执行拒绝策略。
四、常见线程池类型
Java中常见的线程池类型包括:
- FixedThreadPool(固定大小线程池):包含固定数量的线程,适用于需要限制并发线程数量的场景。
- CachedThreadPool(缓存线程池):不固定线程数量,可以根据需要自动创建新线程,适用于短期异步任务。
- SingleThreadPool(单线程池):只包含一个工作线程,保证所有任务按顺序执行,适用于需要保持任务顺序执行的场景。
- ScheduledThreadPool(定时线程池):可以执行定时任务和周期性任务。
- WorkStealingPool(工作窃取线程池):Java 8中引入的一种新类型的线程池,主要用于处理耗时任务,适用于需要大量并行任务、任务之间没有依赖关系的情况。
五、线程池的使用
Java提供了ThreadPoolExecutor类来实现线程池的管理。以下是使用ThreadPoolExecutor创建线程池并提交任务的示例代码:
import java.util.concurrent.*; public class ThreadPoolExample { public static void main(String[] args) { // 创建线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // 核心线程数 4, // 最大线程数 60, // 线程空闲时间 TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() ); // 向线程池提交任务 for (int i = 0; i < 10; i++) { final int task = i; executor.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 正在执行第 " + (task + 1) + " 个任务"); } }); } // 关闭线程池 executor.shutdown(); }
}
此外,Java还提供了Executors工厂类来方便地创建常见的线程池类型。以下是使用Executors创建固定大小线程池、缓存线程池、单线程池和定时线程池的示例代码:
import java.util.concurrent.*; public class ExecutorsExample { public static void main(String[] args) { // 创建固定大小线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 创建缓存线程池 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); // 创建单线程池 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 创建定时线程池 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); // 向线程池提交任务(示例) for (int i = 0; i < 3; i++) { final int task = i; fixedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 正在执行固定大小线程池中的第 " + (task + 1) + " 个任务"); } }); cachedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 正在执行缓存线程池中的第 " + (task + 1) + " 个任务"); } }); singleThreadPool.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 正在执行单线程池中的第 " + (task + 1) + " 个任务"); } }); } // 定时任务示例 scheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.out.println("定时任务执行"); } }, 2, TimeUnit.SECONDS); // 关闭线程池(示例) fixedThreadPool.shutdown(); cachedThreadPool.shutdown(); singleThreadPool.shutdown(); scheduledThreadPool.shutdown(); }
}
六、线程池的拒绝策略
当线程池和队列都满了时,需要采取拒绝策略来处理新的任务。Java线程池支持多种拒绝策略,包括:
- AbortPolicy:直接抛出异常,防止系统崩溃。
- CallerRunsPolicy:在提交者线程中执行任务。
- DiscardPolicy:直接丢弃新任务。
- DiscardOldestPolicy:丢弃最老的任务,尝试重新提交新的任务。
选择合适的拒绝策略,可以避免任务丢失或者对系统造成过度负荷的影响。
七、线程池的优化建议
- 合理设置线程池大小:根据任务类型、执行时间和系统负载等因素来确定线程池大小。如果任务是I/O密集型,可以适当增加线程池大小;如果任务是计算密集型,可以适当减少线程池大小。
- 使用有界队列:无界队列可能会导致内存溢出,因此建议使用有界队列,并根据实际情况选择合适的拒绝策略。
- 动态调整线程池大小:通过调整keepAliveTime的值来动态调整线程池大小。例如,当任务量较少时,可以把keepAliveTime设置较长,让多余的线程等待更长时间以便对突发任务做出快速响应。
- 及时移除空闲线程:保持线程池中的空闲线程数量最小,可以减少系统资源开销。
- 避免线程池饥饿:线程池饥饿会导致任务一直处于排队状态,无法得到处理。可通过调整线程池大小、队列类型和拒绝策略等来避免线程池饥饿。
相关文章:
java线程池详解
在Java中,线程池是一种重要的多线程处理方式,通过管理和复用线程,提高应用程序的性能和响应速度,减少线程创建和销毁的开销,避免线程数量过多导致系统负载过高的问题。本文将详细介绍Java线程池的概念、核心参数、工作…...
五、创建型(建造者模式)
建造者模式 概念 建造者模式是一种创建型设计模式,通过使用多个简单的对象一步步构建一个复杂的对象。它将一个复杂对象的构建过程与其表示分离,从而使同样的构建过程可以创建不同的表示。 应用场景 复杂对象构建:当一个对象有多个属性&…...
CPU超线程技术是什么,怎么启用超线程技术
超线程技术是一种允许单个物理CPU核心模拟成两个逻辑核心的技术,从而提升处理器的并行性能和效率。以下是对超线程技术的详细介绍: 基本概念:超线程(Hyper-Threading,HT)是Intel公司研发的一种技术&#x…...
vba学习系列(7)--考勤表制作
系列文章目录 文章目录 系列文章目录前言一、汇总所有工作表指定区域内容到指定工作表二、汇总所有工作表指定区域内容到指定工作表(带公式)总结 前言 一、汇总所有工作表指定区域内容到指定工作表 Sub CopyRangesToSummary()Dim sourceSheet As WorksheetDim targetSheet As…...
Java学习第九天
相同包下的类可以直接访问,不同包下的类需要导包才可以使用,导包格式:import 包名.类名 final关键字: 常量: 枚举:一种特殊的类型(反编译之后本质就是实例常量,自己定义的类,创建了几…...
【算法系列-链表】链表相交 环形链表II
【算法系列-链表】链表相交&环形链表 文章目录 【算法系列-链表】链表相交&环形链表1. 链表相交1.1 思路分析🎯1.2 解题过程🎬1.3 代码示例🌰 2. 环形链表II2.1 思路分析🎯2.2 代码示例🌰 1. 链表相交 【题目…...
使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务
使用 Go 和 Gin 框架构建简单的用户和物品管理 Web 服务 在本项目中,我们使用 Go 语言和 Gin 框架构建了一个简单的 Web 服务,能够管理用户和物品的信息。该服务实现了两个主要接口:根据用户 ID 获取用户名称,以及根据物品 ID 获…...
【VUE】双端比较算法
假设我们有两个虚拟节点 oldVnode 和 newVnode,它们分别对应的DOM结构为: 我们需要将 oldVnode 更新为 newVnode,这时就可以使用双端比较算法了。算法本质上是将新旧节点进行一次交叉比较,尽可能地重复使用已有的节点来达到最小…...
跨界的胜利:机器学习与神经网络的物理之光
近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...
容器化技术:Docker的基本概念和使用
在现代软件开发和运维中,容器化技术已经成为一种不可或缺的工具。Docker作为容器化技术的代表,以其轻量级、可移植性和隔离性等特点,赢得了广泛的关注和应用。本文将详细介绍Docker的基本概念和使用方法,帮助读者快速上手Docker容…...
EcoVadis认证内容有哪些?EcoVadis认证申请流程?
EcoVadis认证是一个国际性的可持续发展评估平台,旨在帮助全球企业和供应链评鉴其在环境、社会和治理(ESG)方面的表现。该认证框架由法国的检验、认证和检测机构必维集团(Bureau Veritas)创建,得到了众多跨国…...
Windows 搭建 Gitea
一、准备工作 1. 安装 Git:Gitea 依赖 Git 进行代码管理,所以首先需要确保系统中安装了 Git。 下载地址:https://git-scm.com/downloads/win 2. 安装数据库(可选) 默认情况下,Gitea 使用 SQLite 作为内…...
嵌入式面试——FreeRTOS篇(五) 事件标志组
本篇为:FreeRTOS事件标志组篇 1、事件标志组介绍 答: 事件标志位:用一个位,来表示事件是否发生。 事件标志组是一组事件标志位的合集,可以简单的理解事件标志组,就是一个整数。 2、事件标志组的特点 答&am…...
智能听诊器:宠物健康管理的革命
智能听诊器不仅仅是一个简单的监测工具,它代表了宠物健康管理的一次革命。通过收集和分析宠物的生理数据,智能听诊器能够帮助宠物主人和医生更好地理解宠物的健康需求,从而提供更加个性化的护理方案。 智能听诊器通过高精度的传感器…...
dfs +剪枝sudoku———poj2676
目录 前言 lowbit函数 数独 suduku 问题描述 输入 输出 问题分析 子网格位置 优化搜索顺序剪枝1 优化搜索顺序剪枝2 可行性剪枝 代码 前言 lowbit函数 这是一个利用二进制位运算取出二进制数最后一位’1‘的函数 数独 数独大家肯定都玩过,…...
机器学习:关联规则:Apriori算法、FP - Growth算法的原理、应用场景及优缺点介绍
一、关联规则算法概述 关联规则挖掘是数据挖掘中的一个重要任务,用于发现数据集中不同项之间的关联关系。 二、Apriori算法 原理 频繁项集生成:Apriori算法基于一个先验原理,即如果一个项集是频繁的,那么它的所有子集也是频繁的…...
从0开始深度学习(7)——线性回归的简洁实现
在从0开始深度学习(5)——线性回归的逐步实现中,我们手动编写了数据构造模块、损失函数模块、优化器等,但是在现代深度学习框架下,这些已经包装好了 本章展示如果利用深度学习框架简洁的实现线性回归 0 导入头文件 im…...
【网络安全 | Java代码审计】华夏ERP(jshERP)v2.3
未经许可,不得转载。 文章目录 技术框架开发环境代码审计权限校验绕过SQL注入Fastjson反序列化命令执行存储型XSS越权/未授权重置密码越权/未授权删除用户信息越权/未授权修改用户信息会话固定安全建议项目地址:https://github.com/jishenghua/jshERP 技术框架 核心框架:Sp…...
Setting the value of ‘*‘ exceeded the quota
H5之localStorage限额报错quota_exceeded the quota-CSDN博客 Uncaught DOMException: Failed to set a named property on Storage: Setting the value of background exceeded the quota. 超出了 localStorage 的最大长度。...
前端页面模块修改成可动态生成数据模块——大部分数据为GPT生成(仅供学习参考)
前端页面模块修改成可动态生成数据模块: 这些案例展示了如何通过Blade模板将前端页面模块变成可动态生成的模板。通过巧妙使用Blade语法、控制结构、CSS/JS分离、组件复用等技巧,可以大大提高代码的灵活性和复用性。在Laravel的Controller中准备好数据并…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
