当前位置: 首页 > news >正文

Java线程池使用与原理解析(线程池优点、使用方法、参数含义及线程池运转机制)

为什么要使用线程池?

JDK1.5后JUC包添加了线程池相关接口,在Java诞生之初并没有线程池这个概念。刚开始Java程序都是自行创建线程去处理任务。随着应用使用的线程越来越多,JDK开发者们发现有必要使用一个统一的类来管理这些线程,从而有效提高线程的执行效率,减少创建、销毁线程的开销。

大量线程的创建、销毁是非常消耗资源的。创建线程需要消耗一定的内存、CPU资源,大量的线程也会导致大量的线程上下文切换,上下文切换代码也是相当大的,过多的线程导致频繁切换更是可能使系统性能急速下降。另外操作系统对每个进程能创建的线程数也是有限制的,不可能无限创建。但是大量任务也不可能只在主线程处理吧,这样也太慢了。比如下面的例子,创建上万的线程,每个线程打印一下线程名字,观察一下任务管理器,CPU直接用完。这只是简单的任务,要是复杂长时间的任务,整个操作系统可能都会受到影响(CPU利用率长时间下不来,影响其他程序)

public class BadMultiThreadTest {public static void main(String[] args) {Runnable r = () -> {System.out.println("ThreadName-" + Thread.currentThread().getName());};//过多创建线程导致系统资源消耗严重for (int i = 0; i < 10000; i++) {Thread thread = new Thread(r);thread.start();}}
}

线程池就是为了解决上述问题出现的,解决问题的思路很清晰,就是创建好一定数量的线程,有任务来了就用这些线程来执行任务,任务过多把池里面的线程都占用了就放队列排队等候其他任务执行,一旦有空闲线程就可以从队列里面取出任务并执行。有了可控的线程池,系统就不会处于一种可能随时被大量并发导致线程大量创建,最终压跨系统的危险中。

如何使用线程池?

使用线程池去改造上面的例子:

public class MultiThreadPoolTest {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(10);for (int i = 0; i < 10000; i++) {executorService.execute(() -> {System.out.println("ThreadName-" + Thread.currentThread().getName());});}}
}

这次再观察任务管理器,这次CPU占用不会说飙长,而是相对平稳。打印的线程名称就是在ThreadName-pool-1-thread-1到ThreadName-pool-1-thread-10之间变化,说明这一万个任务都是这10个线程处理的。 

线程池的参数含义

上面的例子简单的使用了Excutors工具类来创建了一个固定线程数的线程池。这个工具类还可以创建单线程线程池、可缓存线程池、定时执行任务的线程池等。这些线程池的创建事实上都是在创建一个ThreadPoolExecutor实例,只是通过传递不同参数,实现不同的线程池效果而已。如果我们把里面的参数都搞明白,我们就可以根据实际需求去自定义线程池,实际开发中,我们都应该使用自定义的线程池去处理相关业务,这样能最大提高线程池使用效率,提高系统性能。当然,这还得靠我们对业务的理解,从而定义出合理的线程池。

通过下面这句代码,跟踪源码

Executors.newFixedThreadPool(10);

最终调用的函数如下,它包含了线程池的所有参数注释:

    /*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters.** @param corePoolSize the number of threads to keep in the pool, even*        if they are idle, unless {@code allowCoreThreadTimeOut} is set* @param maximumPoolSize the maximum number of threads to allow in the*        pool* @param keepAliveTime when the number of threads is greater than*        the core, this is the maximum time that excess idle threads*        will wait for new tasks before terminating.* @param unit the time unit for the {@code keepAliveTime} argument* @param workQueue the queue to use for holding tasks before they are*        executed.  This queue will hold only the {@code Runnable}*        tasks submitted by the {@code execute} method.* @param threadFactory the factory to use when the executor*        creates a new thread* @param handler the handler to use when execution is blocked*        because the thread bounds and queue capacities are reached* @throws IllegalArgumentException if one of the following holds:<br>*         {@code corePoolSize < 0}<br>*         {@code keepAliveTime < 0}<br>*         {@code maximumPoolSize <= 0}<br>*         {@code maximumPoolSize < corePoolSize}* @throws NullPointerException if {@code workQueue}*         or {@code threadFactory} or {@code handler} is null*/public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.acc = System.getSecurityManager() == null ?null :AccessController.getContext();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

 下面简单总结一下参数的含义:

参数名称含义
corePoolSize
核心线程数
maximumPoolSize
最大线程数
keepAliveTime+时间单位
空闲线程存活时间
workQueue
任务队列
threadFactory
创建线程的工厂类
handler
被拒绝任务处理器

线程池处理任务的流程

看一下下面的流程图就能清晰知道任务从被提交再到被线程池中线程执行的流程了。

待补充...

使用线程池的优点

根据上面可以简略总结出使用线程池的几点优点:

  • 解决线程创建、销毁等生命周期系统消耗过大问题。因为线程池中的线程一旦创建过,核心线程是会一直驻留在池中待用的,这样任务来了后,直接可以执行,消除了创建线程的系统开销。系统响应更及时,使用更丝滑。
  • 线程池使得系统可控性更强。它避免了系统资源使用不当导致系统崩溃,能更合理的使用CPU和内存资源。

相关文章:

Java线程池使用与原理解析(线程池优点、使用方法、参数含义及线程池运转机制)

为什么要使用线程池&#xff1f; JDK1.5后JUC包添加了线程池相关接口&#xff0c;在Java诞生之初并没有线程池这个概念。刚开始Java程序都是自行创建线程去处理任务。随着应用使用的线程越来越多&#xff0c;JDK开发者们发现有必要使用一个统一的类来管理这些线程&#xff0c;…...

mybatis入门配置

mybatis mybatis是一款持久层框架&#xff0c;用于简化JDBC开发 持久层&#xff1a;负责将数据保存到数据库的那一层代码JavaEE的三层架构&#xff1a;表现层、业务层、持久层、&#xff0c;就相当与mvc设计模式过程中的Controller、service、dao 1.创建一个maven模块&#…...

黑客入门(超级详细版)

据我了解&#xff0c;“黑客”大体上应该分为“正”、“邪”两类&#xff0c;正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善&#xff0c;而邪派黑客则是通过各种黑客技能对系统进行攻击、入侵或者做其他一些有害于网络的事情&#xff0c;因为邪派黑客所…...

Java多线程(三)---synchronized、Lock和volatile

Java内存模型&#xff08;非JVM&#xff09;Java内存模型(Java Memory Model简称JMM)&#xff0c;是一种共享内存模型&#xff0c;是多线程的东西&#xff0c;并不是JVM&#xff08;Java Virtual Machine(Java虚拟机)的缩写&#xff09;&#xff0c;这是俩玩意儿&#xff01;&a…...

JVM-Java内存区域

运行时数据区&#xff1a;1、程序计数器&#xff1a;当前线程所执行的字节码指令的行号指示器。在Java虚拟机的概念模型里&#xff0c;字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令&#xff0c;它是程序控制流的指示器&#xff0c;分支、循环…...

毕业季,毕业论文查重,paper系列五个免费查重网站推荐

推荐五个常用的免费查重网站 注意&#xff1a; &#xff08;1&#xff09;这些网站基本上都可以通过关注公众号或者转发等来获取免费查重机会&#xff0c;但有些也会有字数限制。每个网站的数据库可能不同&#xff0c;所以建议大家多换几个平台查一查&#xff0c;反正是免费的…...

破解票房之谜:为何高票房电影绕不过“猫眼们”?

如此火爆的春节档很多&#xff0c;如此毁誉参半的春节档鲜有。2023开年&#xff0c;集齐张艺谋、沈腾的《满江红》&#xff0c;以及有票房前作打底的《流浪地球2》接连两部春节档电影票房进入前十&#xff0c;为有些颓靡的中国电影市场注入了一针“强心剂”。与票房同样热闹起来…...

订单服务-----遇到的问题及解决方案

订单服务的问题及解决方案问题1&#xff1a;Feign远程调用时丢失请求头编辑出现这个Feign远程调用时丢失请求头的问题是因为Feign在远程调用的时候会创建一个新的请求&#xff0c;但是这个新的请求里啥都没有&#xff0c;没有cookie值&#xff0c;而这个cookie值里有成功登录后…...

项目经理如何度量项目?及项目度量指标实例【静说】

度量项目是项目经理的一个重要职责&#xff0c;通过度量项目&#xff0c;项目经理可以了解项目的进展情况&#xff0c;及时发现问题并采取相应的措施&#xff0c;以确保项目能够按时、按质、按预算完成。 分享给大家一些常见的项目度量指标&#xff1a; 1. 项目进度&#xff…...

我们应该如何优雅的处理 React 中受控与非受控

引言 大家好&#xff0c;我是19组清风。有段时间没有和大家见面了&#xff0c;最近因为有一些比较重要的事情&#xff08;陪女朋友和换了新公司&#xff09;在忙碌所以销声匿迹了一小段时间&#xff0c; 后续会陆陆续续补充之前构建 & 编译系列中缺失的部分&#xff0c;提…...

力扣热题100Day06:20. 有效的括号,21. 合并两个有序链表,22. 括号生成

20. 有效的括号 题目链接&#xff1a;20. 有效的括号 - 力扣&#xff08;Leetcode&#xff09; 思路&#xff1a;使用栈 &#xff08;1&#xff09;遇到左括号就将其对应的右括号压入到栈中 &#xff08;2&#xff09;如果遇到右括号 a. 如果弹出的元素与当前不等&#xff…...

【Yolov5】保姆级别源码讲解之-推理部分detect.py文件

推理部分之detect.py文件讲解1.下载Yolov5的源码2. 主函数讲解3.文件标头的注释4. main函数的5. run函数5.1 第一块参数部分5.2第二块&#xff0c;传入数据预处理5.3 第三块创建文件夹5.4 第四块 加载模型的权重5.5 第五块 Dataloader 加载模块5.6 第六块 推理部分 Run inferen…...

无重叠区间-力扣435-java贪心策略

一、题目描述给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。示例 1:输入: intervals [[1,2],[2,3],[3,4],[1,3]]输出: 1解释: 移除 [1,3] 后&#xff0c;剩下的区间没有重叠。…...

Python使用VTK对容积超声图像进行体绘制(三维重建)

目录VTK简介什么是体绘制&#xff1f;体绘制效果图流程CodeQ&AReferenceVTK简介 VTK&#xff08;Visualization Toolkit&#xff09;是一个用于3D计算机图形学、图像处理和可视化的开源软件包。它包括一组C类和工具&#xff0c;可以让用户创建和处理复杂的3D图形和数据可视…...

JAVA设计模式之工厂模式讲解

目录 前言 开始表演 前言 Java中使用工厂模式的主要原因是为了实现代码的灵活性和可维护性。工厂模式是一种创建型设计模式&#xff0c;它提供了一种将对象的创建和使用进行分离的方式。具体来说&#xff0c;工厂模式可以将对象的创建过程封装在一个独立的工厂类中&#xff…...

近万字概述L3及以上自动驾驶故障运行和故障安全机制

本文描述了对ADS的FO和FS机制的评估方法。当系统不能按预期运行时,ADS将使用FO和FS机制。这些机制使ADS能够在最大程度上达到使车辆及其乘员脱离危险的MRC。定义、测试和验证实现MRC的FO和FS策略是确保ADS安全运行和部署的重要步骤。 MRC在SAE J3016中被定义为: 用户或ADS在…...

kafka入门到精通

文章目录一、kafka概述&#xff1f;1.定义1.2消息队列1.2.1 传统消息队列的使用场景1.2.2 消息队列好处1.2.3 消息队列两种模式1.3 kafka基础架构二、kafka快速入门1.1使用docker-compose安装kafka1.2测试访问kafka-manager1.3 查看kafka版本号1.4 查看zookeeper版本号1.5 扩展…...

es-09模糊查询

模糊查询 前缀搜索&#xff1a;prefix 概念&#xff1a;以xx开头的搜索&#xff0c;不计算相关度评分。 注意&#xff1a; 前缀搜索匹配的是term&#xff0c;而不是field。前缀搜索的性能很差前缀搜索没有缓存前缀搜索尽可能把前缀长度设置的更长 语法&#xff1a; GET <ind…...

57 - 深入解析任务调度

---- 整理自狄泰软件唐佐林老师课程 文章目录1. 问题1.1 思考1.2 实例分析&#xff1a;问题分析及解决2. 深入讨论2.1 任务调度的定义2.2 关于调度算法的分类2.3 什么时候进行任务调度2.4 任务的分类2.5 关于优先级调度2.6 问题2.7 调度算法的终极目标2.8 课后扩展1. 问题 系统…...

CAN总线开发一本全(3) - 微控制器集成的FlexCAN外设

CAN总线开发一本全&#xff08;3&#xff09; - 微控制器集成的FlexCAN外设 苏勇&#xff0c;2023年2月 文章目录CAN总线开发一本全&#xff08;3&#xff09; - 微控制器集成的FlexCAN外设引言硬件外设模块系统概要总线接口单元 - 寄存器清单数据结构 - 消息缓冲区MB初始化过…...

OpenClaw+Qwen3-14b_int4_awq:3种降低token消耗的实战技巧

OpenClawQwen3-14b_int4_awq&#xff1a;3种降低token消耗的实战技巧 1. 为什么我们需要关注token消耗 第一次看到OpenClaw的token账单时&#xff0c;我差点从椅子上跳起来。一个简单的文件整理任务竟然消耗了接近5000个token&#xff0c;这还只是测试环境下的单次运行。当我…...

KDD_CUP99数据集预处理与模型性能验证(附处理代码与数据集)

1. KDD_CUP99数据集入门指南 第一次接触KDD_CUP99数据集时&#xff0c;我也被它庞大的数据量和复杂的特征结构吓了一跳。这个数据集是网络安全领域最经典的入侵检测基准数据集之一&#xff0c;包含了模拟军事网络环境中各种攻击类型的网络连接记录。原始数据集有近500万条记录&…...

Java应用等保三级合规改造:3天完成代码层、配置层、运维层全栈优化(附Checklist)

第一章&#xff1a;Java应用等保三级合规改造全景图等保三级是国家网络安全等级保护制度中面向重要信息系统的核心要求&#xff0c;对Java应用而言&#xff0c;合规改造不是单一技术点的修补&#xff0c;而是一套覆盖开发、运行、运维全生命周期的安全治理工程。其核心目标在于…...

拯救者笔记本性能优化终极指南:如何用Lenovo Legion Toolkit释放硬件潜力

拯救者笔记本性能优化终极指南&#xff1a;如何用Lenovo Legion Toolkit释放硬件潜力 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionTool…...

智谱CEO张鹏:将推理性能压榨至极限 不为短期盈利,而是为高质量Token消耗指数曲线

雷递网 乐天 3月31日智谱CEO张鹏今日在智谱2025年年报沟通会上表示&#xff0c;智谱曾经历过质疑&#xff0c;经历过挫折&#xff0c;但无数事实反复验证了一个判断——智能上界的提升&#xff0c;是大模型AGI时代唯一的"第一性"。张鹏说&#xff0c;AGI时代的商业价…...

ARL灯塔扫不出指纹?手把手教你用Python脚本批量导入指纹库,提升资产识别准确率

ARL灯塔指纹识别优化实战&#xff1a;Python脚本批量导入与精准率提升指南 资产侦察灯塔&#xff08;ARL&#xff09;作为渗透测试领域的重要工具&#xff0c;其核心价值在于准确识别目标资产的技术特征。然而许多中级用户发现&#xff0c;默认指纹库在面对特定行业或新型资产…...

Win11Debloat开源工具:焕新Windows系统体验的极简优化指南

Win11Debloat开源工具&#xff1a;焕新Windows系统体验的极简优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter an…...

推荐算法闲谈:如何在不同业务场景下理解和拆解核心指标

巧解决的是能不能学好&#xff0c;而指标分析解决的是这次改动是否真正创造了业务价值&#xff0c;以及为什么。一个非常常见、但又极易被忽视的事实是&#xff1a;推荐系统并不存在一套放之四海而皆准的核心业务指标。不同产品形态、不同交互方式、不同公司发展阶段&#xff0…...

一开口就聊到客户心坎里的沟通话术

先把人聊顺&#xff0c;事自然就顺了一位资深顾问&#xff0c;老客户复购和转介绍特别多。她的秘诀很简单&#xff1a;先聊人&#xff0c;再聊事。有次对接一位态度疏离的客户&#xff0c;她没直接问方案&#xff0c;而是看到客户朋友圈刚出去玩&#xff0c;便说&#xff1a;“…...

Stable-Diffusion-v1-5-archive多风格生成效果:复古海报/科技感UI/手绘插画实拍

Stable Diffusion v1.5 Archive多风格生成效果&#xff1a;复古海报/科技感UI/手绘插画实拍 1. 模型介绍与核心能力 Stable Diffusion v1.5 Archive是经典SD1.5文生图模型的归档版本&#xff0c;作为AI图像生成领域的"常青树"&#xff0c;它依然保持着强大的通用图…...