Java线程:线程池详解(ThreadPoolExecutor构造器七个参数、线程池处理Runnable/Callable任务)

article/2025/7/19 7:00:05

认识线程池

  1. 什么是线程池

    线程池就是一个可以复用线程的技术

  2. 不使用线程池的问题

    用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。

  3. 为什么线程池可以提高系统的工作性能

    因为线程池可以控制线程和任务的数量,因此不会因为线程或者任务过多而导致系统瘫痪

  4. 线程池工作原理图

在这里插入图片描述

如何创建线程池

代表线程池的接口ExecutorService

接口是无法直接创建对象的,因此要用到他的实现类,常用创建对象来代表一个具体线程池

如何得到线程池对象

在这里插入图片描述

ThreadPoolExecutor构造器七个参数(面试重点

核心线程数量+临时线程数量=最大线程数量

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

请添加图片描述
请添加图片描述
以餐厅来举例理解
请添加图片描述
ctrl+鼠标左键点击ThreadPoolExecutor选择参数最多的一个
在这里插入图片描述
LinkedBlockingQueue<>()不限制大小

ArrayBlockingQueue<>(4)自己设置大小

public static void main(String[] args) {//1.通过ThreadPoolExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());}

线程池注意事项(面试重点)

0. 线程池分层的任务调度策略

线程池的核心目标是平衡资源利用和任务处理效率 ,同时避免过度消耗系统资源(如CPU、内存)。为了实现这一目标,线程池采用了分层的任务调度策略:

  • 优先使用核心线程 :核心线程是线程池的“主力”,负责处理大部分任务。
  • 任务积压时使用任务队列 :当核心线程都在忙时,新任务会被放入任务队列中等待执行,而不是立即创建新线程。
  • 最后才创建临时线程 :只有在任务队列已满且核心线程都在忙的情况下,才会创建临时线程。
    这种分层策略的设计目的是尽量减少线程的创建和销毁开销 ,因为线程的创建和销毁是非常昂贵的操作。

总结:线程池的任务调度优先级是:核心线程 →任务队列 →临时线程

1.临时线程什么时候创建

新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。

2.什么时候会开始拒绝新任务?

核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务

线程池处理Runnable任务

ExecutorService的常用方法

请添加图片描述

execute()

相关代码:

public class MyRunnable implements Runnable{@Overridepublic void run() {//描述任务是干什么的System.out.println(Thread.currentThread().getName()+"Wolves487");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}
}
/*线程池的创建*/
public class ThreadPoolTest1 {public static void main(String[] args) {//1.通过ThreadPoolExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());Runnable target = new MyRunnable();pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //复用前面的核心线程pool.execute(target); //复用前面的核心线程}
}

请添加图片描述

.shutdown() .shutdownNow()

线程池启动后是不会自动关闭的,因为在开发中本来就要保证线程池不死亡

请添加图片描述

pool.shutdown(); //等线程池的所有任务全部执行完后,再关闭线程池

请添加图片描述

pool.shutdownNow(); //立即关闭线程池,不管任务是否执行完(可能出现异常

请添加图片描述
实际开发中一般不关闭线程池

核心线程在忙,任务队列占满了的时候,并且还可以创建临时线程,等新任务过来时就会创建临时线程

让每个任务执行线程的时候休眠时间无限大,就可以保证核心线程一直忙了

public class MyRunnable implements Runnable{@Overridepublic void run() {//描述任务是干什么的System.out.println(Thread.currentThread().getName()+"Wolves487");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}
}

case1:未创建临时线程
在这里插入图片描述

case2:创建了临时线程
在这里插入图片描述

case3:达到最大线程数,触发拒绝策略

在这里插入图片描述

/*线程池的创建*/
public class ThreadPoolTest1 {public static void main(String[] args) {//1.通过ThreadPoolExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());Runnable target = new MyRunnable();pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //进入任务队列pool.execute(target); //进入任务队列pool.execute(target); //进入任务队列pool.execute(target); //进入任务队列//到临时线程创建的时机了pool.execute(target);pool.execute(target);// 3+2=5 到新任务的拒绝时机了pool.execute(target);}
}
补充:新任务拒绝策略

在这里插入图片描述

线程池处理Callable任务

ExecutorService的常用方法

请添加图片描述

/*线程池的创建*/
public class ThreadPoolTest2 {public static void main(String[] args) throws ExecutionException, InterruptedException {//1.通过ThreadPoolExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//2、使用线程处理Callable任务Future<String> f1 = pool.submit(new MyCallable(100));Future<String> f2 = pool.submit(new MyCallable(200));Future<String> f3 = pool.submit(new MyCallable(300));Future<String> f4 = pool.submit(new MyCallable(400));System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());System.out.println(f4.get());}
}
/*** 1、实现Callable接口*/
public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}//2、重写call方法@Overridepublic String call() throws Exception {//描述线程的任务,返回线程执行返回后的结果//需求:求1~n的和并返回int sum = 0;for (int i = 0; i <= n; i++) {sum += i;}return Thread.currentThread().getName()+":n"+"的和为"+sum;}
}

在这里插入图片描述

Executors工具类实现线程池

Executors是一个线程池的工具类,提供了很多静态方法,用于返回不同特点的线程池对象

请添加图片描述

//1.通过Executors创建一个线程池对象ExecutorService pool = Executors.newFixedThreadPool(3);//新建固定线程数的线程池ExecutorService pool1 = Executors.newSingleThreadExecutor();//新建1个线程数的线程池

注意:这些方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象

核心线程数量到底配置多少

  1. 计算密集型任务

    核心线程数量 = CPU的核数+1

  2. IO密集型任务

    核心线程数量 = CPU的核数+2

Executors使用可能存在的陷阱(注意)

大型并发系统环境中(如淘宝、京东)使用Executors如果不注意可能会出现系统风险

如阿里巴巴开发手册中写到
请添加图片描述


http://www.hkcw.cn/article/XXxfVXagxQ.shtml

相关文章

华为OD机试真题——开放日活动/取出尽量少的球(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》 华为OD机试真题《开放…

day14 leetcode-hot100-25(链表4)

141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; 1.哈希集合 思路 将节点一个一个加入HashSet&#xff0c;并用contains判断是否存在之前有存储过的节点&#xff0c;如果有便是环&#xff0c;如果没有便不是环。 具体代码 /*** Definition for singly-linked list.*…

低碳理念在道路工程中的应用-预制路面

一、引子 在上一篇文章里&#xff0c;给大家介绍了预制基层的应用&#xff0c;有人提出&#xff0c;既然基层能够预制&#xff0c;那么&#xff0c;道路面层能不能预制呢&#xff0c;有没有相关的研究成果和应用实例呢&#xff1f;答案是肯定的&#xff0c;在本篇文章中&#x…

React---day5

4、React的组件化 组件的分类&#xff1a; 根据组件的定义方式&#xff0c;可以分为&#xff1a;函数组件(Functional Component )和类组件(Class Component)&#xff1b;根据组件内部是否有状态需要维护&#xff0c;可以分成&#xff1a;无状态组件(Stateless Component )和…

Muplayer——轻量级在线JavaScript 音乐播放器

简单的 JavaScript 音乐播放器 GitHub 地址&#xff1a;https://github.com/Wcowin/Muplayer 在线地址&#xff1a;https://wcowin.work/Muplayer/ 本项目是一个基于原生 JavaScript、HTML 和 CSS 实现的响应式音乐播放器&#xff0c;支持本地音乐添加、播放列表管理、搜索、…

毫秒断电,安全守护|维安WPB系列主动型熔断器重磅登场!

1 主动型熔断器 新能源时代的“主动保护”趋势 随着新能源汽车行业的高速发展&#xff0c;其相关安全事故也层出不穷。为此&#xff0c;工信部于2025 年3月 28 日组织制定了强制性国家标准《电动汽车用动力蓄电池安全要求》&#xff08;GB38031-2025&#xff09;&#xff0c…

Java—— 多线程 第二期

等待唤醒机制(生产者和消费者) 说明 之前的多线程是谁抢到CPU的执行权谁执行&#xff0c;而等待唤醒机制作为一种经典的多线程协作模式&#xff0c;可以实现线程的交替执行。 成员 实现等待唤醒机制需要三个成员&#xff1a;生产者、消费者、标志位 可以分别看作厨师、吃货、…

2025年最新《Python程序设计》题库(含答案)

判断题填空题选择题程序题 点击文末名片可以下载python工具和完整题库&#xff01; 第 1 章 基础知识 &#xff08;部分展示&#xff09; 1、 Python 是一种跨平台、开源、免费的高级动态编程语言。 2、 Python 3.x 完全兼容 Python 2.x。 3、 Python 3.x 和 Python 2.x 唯…

【AI非常道】二零二五年五月,AI非常道

经常在社区看到一些非常有启发或者有收获的话语&#xff0c;但是&#xff0c;往往看过就成为过眼云烟&#xff0c;有时再想去找又找不到。索性&#xff0c;今年开始&#xff0c;看到好的言语&#xff0c;就记录下来&#xff0c;一月一发布&#xff0c;亦供大家参考。 前面的记…

Linux入门(十一)进程管理

Linux 中每个执行的程序都称为一个进程&#xff0c;每个进程都分配一个ID号&#xff08;PID&#xff09; 每个进程都可能以两种方式存在&#xff0c;前台&#xff08;屏幕上可以操作的&#xff09;和后台&#xff08;屏幕上无法看到的&#xff09;&#xff0c;一般系统的服务都…

晨控CK-UR12与西门子PLC配置Modbus TCP通讯连接操作手册

晨控CK-UR12与西门子PLC配置Modbus TCP通讯连接操作手册 晨控CK-UR12系列作为晨控智能工业级别RFID读写器,支持大部分工业协议如RS232、RS485、以太网。支持工业协议Modbus RTU、Modbus TCP、Profinet、EtherNet/lP、EtherCat以及自由协议TCP/IP等。 本期主题&#xff1a;围绕…

Python使用

Python学习&#xff0c;从安装&#xff0c;到简单应用 前言 Python作为胶水语言在web开发&#xff0c;数据分析&#xff0c;网络爬虫等方向有着广泛的应用 一、Python入门 相关基础语法直接使用相关测试代码 Python编译器版本使用3以后&#xff0c;安装参考其他教程&#xf…

高德地图应用OceanBase单元化构建下一代在线地图服务

IEEE International Conference on Data Engineering (ICDE) 是数据库和数据工程领域的顶级学术会议之一&#xff08;与SIGMOD、VLDB并成为数据库三大顶会&#xff09;&#xff0c;自1984年首次举办以来&#xff0c;每年举办一次。ICDE涵盖广泛的主题&#xff0c;包括数据库系统…

软考-系统架构设计师-第十九章 嵌入式系统架构设计理论与实践

嵌入式系统架构设计理论与实践 19.1 嵌入式系统发展历程19.2 嵌入式系统硬件19.3 嵌入式系统软件19.4 嵌入式系统软件架构设计方法19.5 嵌入式系统软件架构实践 19.1 嵌入式系统发展历程 发展历程硬件软件主要特点单片微型计算机&#xff08;SCM&#xff09;单片机无操作系统 …

DeepSeek-R1 重磅升级,智能体验再进化!

DeepSeek AI 爱好者们注意啦&#xff01;DeepSeek R1 模型完成小版本升级&#xff0c;新版本 DeepSeek-R1-0528 震撼登场。想体验超强思考与推理能力&#xff1f;官方网站、APP、小程序&#xff0c;一键开启 “深度思考” 功能&#xff0c;新版等你来探索&#xff01;API 也同步…

预处理深入详解:预定义符号、宏、命名约定、命令行定义、条件编译、头文件的包含

目录 一、预定义符号 二、#define定义常量 三、宏 &#xff08;一&#xff09;#define定义宏 &#xff08;二&#xff09;带有副作用的宏参数 &#xff08;三&#xff09;宏替换的规则 &#xff08;四&#xff09;宏和函数的对比 四、#和## &#xff08;一&#xff09…

深度解析:跨学科论文 +“概念迁移表” 模板写作全流程

跨学科论文速通&#xff01;融合“概念迁移表”的写作导航模板 你的论文是否曾被导师皱眉评价为“四不像”&#xff1f;不同学科的术语在稿纸上打架&#xff0c;核心逻辑若隐若现&#xff1f; 别让心血沦为学术混搭的牺牲品。一张精心设计的 概念迁移表&#xff0c;能将两个看…

Linux安装及管理程序

1 Linux应用程序基础 1.1 Linux 命令与应用程序的关系 在 Linux 操作系统中&#xff0c;一直以来命令和应用程序并没有特别明确的区别&#xff0c;从长期使用习惯来看&#xff0c;可以通过以下描述来对两者进行区别&#xff1a; 应用程序命令的执行文件大多比较小&#xff0…

历年南京大学计算机保研上机真题

2025南京大学计算机保研上机真题 2024南京大学计算机保研上机真题 2023南京大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school Count Number of Binary Strings 题目描述 Given a positive integer n n n ( 3 ≤ n ≤ 90 3 \leq n \leq 90 3≤n≤…

酒店管理系统设计与实现

本科毕业设计(论文) 设计(论文)题目 酒店管理系统设计与实现 学生姓名 学生学号 所在学院 专业班级 校内指导教师 李建 企业指导教师 毕业设计(论文)真实性承诺及声明 学生对毕业设计(论文)真实性承诺 本人郑重声明:所提交的毕业设计(论文)作品是本人在指导教师的指…