十分钟深入理解Java线程池源码及设计原理

java多线程——线程池 在Java中,线程池是一种用于管理和复用线程的技术,它可以减少创建和销毁线程的开销,提高系统的性能和响应速度。Java标准库提供了包,其中包含了接口及其实现类,用于创建和管理线程池。 阅读详情

一、说明

下面如果有贴出源码,对应的源码是JDK8

主要的源码类

java.util.concurrent.ThreadPoolExecutor、
java.util.concurrent.ThreadPoolExecutor.Worker
java.util.concurrent.AbstractExecutorService

1. 类继承图

二、线程池的状态

三、源码分析

1. 完整的线程池构造方法
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
2. ctl

内部有重要的成员变量ctl,类型是AtomicInteger,低29位表示线程池中线程数,通过高3位表示线程池的运行状态

COUNT_BITS的值是29

  • RUNNING:-1 << COUNT_BITS,即高3位为111,该状态的线程池会接收新任务;
  • SHUTDOWN: 0 << COUNT_BITS,即高3位为000,该状态的线程池不会接收新任务;
  • STOP : 1 << COUNT_BITS,即高3位为001;
  • TIDYING : 2 << COUNT_BITS,即高3位为010, 所有的任务都已经终止;
  • TERMINATED: 3 << COUNT_BITS,即高3位为011, terminated()方法已经执行完成
3. 任务的执行

execute --> addWorker --> Thread.start --> (Thread.run) --> runTask --> getTask

3.1execute(Runnable command)

大致分三个步骤

  • 当前运行的线程数量是否小于corePoolSize,直接尝试addWorker()
  • 往阻塞队列里面放入Runnable任务
  • 如果队列已经满了,直接尝试addWorker()

3.2 addWorker(Runnable firstTask, boolean core)

  • 前置判断线程池的状态
  • 通过CAS操作让ctl加1,表示运行线程数增加1个
  • 构造一个Worker w,这里要特别注意构造方法里面的这行代码,this.thread = getThreadFactory().newThread(this),可以看到构造方法内,有一个Thread对象,其使用了ThreadFactory构造了一个新的线程,并且线程的runable是worker本身。
  • 执行w.thread.start(),也就是说,当该线程被运行时,Worker中的run方法会被执行

3.3 runWorker(Worker w)

通过循环调用getTask()获取要执行的任务task
beforeExecute
task.run()
afterExecute

3.4 getTask()

源码如下:

private Runnable getTask() {
	Boolean timedOut = false;
	// 是否最后的 poll() 超时了?
	for (;;) {
		int c = ctl.get();
		int rs = runStateOf(c);
		// Check if queue empty only if necessary.
		if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
			decrementWorkerCount();
			return null;
		}
		int wc = workerCountOf(c);
		Boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
		// worker是否需要被淘汰
		if ((wc > maximumPoolSize || (timed && timedOut))
		            && (wc > 1 || workQueue.isEmpty())) {
			// 这里会让线程的数量记录减,后面的return null,会导致runWorker没有获取到数据而让run()方法走到尽头,最终当前线程结束
			if (compareAndDecrementWorkerCount(c))
			                return null;
			continue;
		}
		try {
			// 如果需要回收一部分线程,那么超时时间keepAliveTime后拿不到就数据就继续循环调用,就可以在下一次循环的时候进行线程结束回收了;否则一直阻塞下去
			Runnable r = timed ?
			                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
			                workQueue.take();
			if (r != null)
			                return r;
			timedOut = true;
		}
		catch (InterruptedException retry) {
			timedOut = false;
		}
	}
}

四、任务执行,带返回值的

源码如下:

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

代码比较简单,把任务封装成一个既实现Runnable, 也实现Future<v style="margin: 0px; padding: 0px;">的接口,这个时候就可以调用execute()进行实现了</v>

Java_supermanNO1:专注于Java开发技术的研究与知识分享!

————END————

  • 点赞(编辑不易,感谢您的支持)

  • …

  • 转发(分享知识,传播快乐)

  • …

  • 关注(每天更新Java开发技术)

  • …

java实现线程池(附完整源码) 阅读详情

相关推荐

java线程池完整代码

java 线程池 完整 源码 java 线程池 完整 源码

Java线程池

线程池能够存储一定数量的线程,当我们需要时,就从池中取出使用,用完再还给线程池。为什么要使用线程池?线程池能够减少每次启动、销毁线程的损耗,同时,在执行任务时,不需要等待线程创建就可直接执行,提高了响应速度,此外,由线程池统一调度和分配线程,有利于线程的管理。

2301_76161469的博客 1853

DeepSeek 在 PostgreSQL 中,执行 `DELETE` 操作后,数据占用的空间并不会立即释放给操作系统

操作后,数据占用的空间并不会立即释放给操作系统。这是 PostgreSQL 的 MVCC(多版本并发控制)机制决定的——删除的数据只是被标记为“死元组”,物理空间仍然被表占用。这是最彻底的释放方式,会将表重写为一个没有空洞的新文件,将空间返回给操作系统。如果你的表非常大(如几百GB),或者这是生产环境的核心表,建议优先考虑。你可以告诉我你的表大概多大、是否能接受锁表,我可以给你更精确的建议。要真正释放空间,需要根据你的实际需求,从以下三种方案中选择一种。如果你既想彻底释放空间,又无法接受锁表,

m0_37843156的博客 402

一文带你熟透Java线程池的使用及源码

一文带你熟透Java线程池的使用及源码 在单个线程使用过程中遇到的问题(new Thread().start): 线程的频繁创建与销毁 线程执行数据多且高频,频繁CPU上下文切换,造成CPU的资源浪费

生生不息,则源源不断 1210

⑩电子产品拆解分析-家用无线遥控开关433Mhz

①免布线随意贴,装上就能使用解决单线开关烦恼;②遥控配对简单,无线通讯距离长,信号可穿墙;

a6662580的博客 4681

自然语言处理6 -- 情感分析

1 概述 情感分析是自然语言处理中常见的场景,比如淘宝商品评价,饿了么外卖评价等,对于指导产品更新迭代具有关键性作用。通过情感分析,可以挖掘产品在各个维度的优劣,从而明确如何改进产品。比如对外卖评价,可以分析菜品口味、送达时间、送餐态度、菜品丰富度等多个维度的用户情感指数,从而从各个维度上改进外卖服务。 情感分析可以采用基于情感词典的传统方法,也可以采用基于深度学习的方法,下面详细讲解 ...

谢杨易的博客 5万+

Java 线程池的基本介绍和使用

在 Java 中,可以利用线程做很多事情,创建多个线程来高效的完成任务,例如 Tomcat 用多个线程来接收和处理请求,我们也可以创建多个线程来批量处理数据,原本串行执行的任务变成并行执行,充分利用 CPU 多个核的性能。这样子确实能够并发完成任务,但是也带了问题:创建的线程数量不可控制,一个任务就创建一个线程,当任务量庞大的时候,会带来极大的,反复创建、销毁线程。⭐ 在实际开发中,如果需要创建超过五个线程执行类似的任务,就可以考虑使用线程池了。

BASK2311的博客 542

uniapp - 解决报错Error in event handler for “service.requestComponentInfo“: “TypeError: cannot read prop

uniapp,报错,Error in event handler for "service.requestComponentInfo": "TypeError: cannot read properties of undefined (reading 'matches')",h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,如何解决这个问题,一直报错,uniapp报错Error,都检查了还是报错,怎么解决这个错误,uniapp出现Error in event han

🏆 前端领域优质创作者 6379

深入源码分析Java线程池的实现原理

在《深入源码分析Java线程池的实现原理》这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理。 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建议这样使用。 关于这个问题,在那篇文章中并没有深入的展开。作者之所以这么说,是因为这种创建线程池的方式有很大的隐患,稍有不慎就有可能导致线上故障,如:一次Java线程池误用引发的血案和总结( ht...

weixin_38167847的博客 90

使用python中pypower进行电力潮流计算

使用python中pypower进行电力潮流计算

总裁余(余登武)博客 4860

R语言广义加型模型(GAM)的运用例子及实现教程

一旦拟合了广义加型模型,我们可以查看模型摘要和诊断,以评估模型的质量和拟合情况。# 查看模型摘要响应变量:mpg(汽车的燃油效率)拟合函数:mpg ~ s(hp) + s(wt)

Mrrunsen的博客 3444

十分钟登顶Git!13万字!腾讯高工手写JDK源码笔记 带你飙向实战

灵魂一问,我们为什么要学习JDK源码? 当然不是为了装,毕竟谁没事找事虐自己 ... 1、面试跑不掉。现在只要面试Java相关的岗位,肯定或多或少会会涉及JDK源码相关的问题。 2、弄懂原理才不慌。我们作为JDK的使用者,虽然说天天用得很开心,但是有时候遇到问题还是得跟到底层源码去看看,才能帮助我们更好的弄懂原理, 3、学习优秀的代码、思想和模式。JDK毕竟是一个优秀的代码库,我们天天用,源码也就在里面,作为一个有志向的程序员,读一读源码也能让我们吸取到更多优秀的思想和模式。 那么源码难吗? 废

kxkxyzyz的博客 134

【Flink】FLink session yarn kerberos认证报错 PortUnreachableException: ICMP Port Unreachable

本篇博客是在上一篇博客:【Flink】FLink session yarn kerberos认证报错 KrbException: Cannot locate default realm还没找到原因的时候做的一次尝试。因为项目需要,我们需要对接华为认证的yarn集群,运行flink任务,我们的任务分为两种,yarn pre-job模式和flink session模式。我们在配置文件中配置如下# kerberos认证需要的东西提交任务的脚本如下。

九师兄 1267

java两层审核表怎么建_备战金三银四:京东JAVA研发4面面试宝典

一面:(约五十分钟)1 自我介绍,讲一下项目中的多线程实现2 Java的线程池的参数,拒绝策略,阻塞队列等实现和使用3 fixethreadpool使用的是什么阻塞队列,如果使用arrayblockingqueue或者linkedblockingqueue会有什么问题。4 ArrayList和linkedlist有什么区别,扩容呢5 hashmap,hashtable,concurrenthash...

weixin_32242475的博客 119

有限元分析-静力学分析-与分析解对比-——以阶梯轴的静力分析为例——静态结构分析

150mm,a=300mm{a=300mm}a=300mm,b=200mm{b=200mm}b=200mm,L=1000mm{L=1000mm}L=1000mm,F=300kN{F=300kN}F=300kN,材料为45,弹性模量E=2.1e11Pa{E=2.1e11Pa}E=2.1e11Pa,泊松比v=0.28{v=0.28}v=0.28,屈服应力δs=355MPa{δ_s=355MPa}δ。使用line body生成的模型,可以选择自动划分网格的,WB会将以梁单元将其划分完成,例如图2所示。

qq_15963745的博客 66

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

2025 Java面试核心考点:从八股文到原理深挖与表达

技术面试中,基础概念的考察早已不是简单的记忆背诵,而是通过追问原理来评估候选人的计算机功底与思维深度。以Java后端开发为例,无论是HashMap的扩容机制、线程池的参数调优,还是JVM内存模型与垃圾回收算法,背后都暗含着数据结构、并发控制与系统设计的通用逻辑。理解这些底层原理,不仅有助于应对面试中的高频追问,更能指导实际项目中的性能优化与故障排查。从集合框架到并发编程,从Spring IOC/AOP到MySQL索引与Redis缓存,再到JDK21虚拟线程等新特性,系统梳理核心知识点并掌握清晰的表达路径,是

weixin_31102231的博客 265

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

java epoll select_Java后端常见面试题

写在前面:本来每个问题上面都有超链接,都有相对应的答案。但是不知道为什么就是不能发布。想看每个问题的详细解答和知识点,点击文末左下角的“阅读原文”即可查看!作者的话Java基础问题String的’+’的性能及原理java之yield(),sleep(),wait()区别详解-备忘笔记深入理解Java Stream流水线抽象 & abstract关键字Java final 修饰符知...

weixin_39990401的博客 193

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

2023春招Java笔试核心考点拆解与实战技巧

在Java开发者招聘中,笔试环节越来越注重候选人真实的编码功底与问题排查能力,而非单纯的语法记忆。从集合框架的底层实现(如HashMap的扩容与红黑树转换)、JVM内存管理与OOM场景分析,到线程池参数配置和Spring事务失效等高频考点,每一道题都映射着工程实践中的真实痛点。理解这些原理不仅能帮助开发者写出更健壮的代码,还能在系统出现内存溢出、并发竞争时快速定位根因。无论是应届生准备春招,还是有一定经验的开发者寻求跳槽,掌握这些底层知识与应试技巧都至关重要。本文以2023小满春招JAVA研发岗笔试为例,逐

weixin_34379433的博客 432

后端开发常问面试题集锦(附链接)

Java基础问题String的'+'的性能及原理java之yield(),sleep(),wait()区别详解-备忘笔记深入理解Java Stream流水线抽象 &amp; abstract关键字Java final 修饰符知识点总结(必看篇)Java中的static关键字解析Java 回调机制解读Java抽象类与oop三大特征Java时间和时间戳的相互转换Java为什么要使用内部类?Synchr...

总有些事,值得你去努力 1万+

Java行情低谷期,如何靠技术深度逆势突围

技术行业的周期性波动中,编程语言的兴衰往往被过度解读。Java作为企业级后端的基础设施,其生命力源于庞大的生态与持续演进的标准规范。JVM的内存模型、垃圾回收机制与并发编程模型,构成了Java开发者解决问题的底层原理;而Spring Boot等框架则将这些原理封装为高效的生产力工具。在云原生与高并发场景下,深入理解虚拟机、并发工具链与源码设计,能让开发者从“会用框架”进阶到“解决复杂问题”。面对招聘市场的结构分化,具备JVM调优、高并发处理能力的工程师始终稀缺。当下Java行情虽处调整期,但技术价值的沉淀正

weixin_32288959的博客 280

双非Java工程师冲击大厂:面试准备与实战复盘

在Java开发者的职业进阶中,扎实的原理认知与高效的面试准备同样重要。JVM内存模型、并发编程、Spring容器等核心知识点,不仅是日常编码的基础,更是大厂技术面试的高频考点。针对学历背景不占优势的求职者,如何通过系统化的知识梳理、项目复盘和应答技巧来弥补差距,成为实现职业跃迁的关键。一位双非院校背景的Java工程师,完整复盘其冲击大厂的技术准备路径,涵盖算法刷题策略、八股文深度理解、系统设计框架以及现场沟通心态,为同样处境的开发者提供可操作的实战参考。

weixin_26899659的博客 246

Java面试八股文:从JVM并发到MySQL索引的进阶复习路线

在Java后端开发岗位的面试中,基础知识决定候选人的技术深度。JVM内存模型、并发编程、MySQL索引与事务、缓存一致性等话题,是面试官考察候选人系统工程能力的高频切入点。理解JVM的垃圾回收机制与类加载过程,掌握synchronized、volatile与AQS的底层原理,熟悉B+树索引与MVCC的协作方式,是构建完整知识体系的关键。从原理到实践,分布式系统与中间件组件(如Kafka、Redis)的性能设计思路同样值得深入探究。这套复习路线适用于准备跳槽或系统梳理Java服务端核心技能的开发者,帮助提升面

weixin_34050519的博客 388

粉丝投稿!春招参加百度3月补录上岸记录(三轮面试面经)附:Java面试总结

前言 先说下楼主经历: 双非本,去年五月份至今一直在JD实习,拿到了JD的offer后,偶然的机会(boss上)就开始面试 部门是百度云cdn 具体好像是做音视频相关的,主要语言是Java 和我本人相符 一、二、三面两天面完,具体的问题记不清楚了,以下内容仅凭回忆(上班摸鱼写的): 一面面经: 是个小姐姐,但是很严肃 自我介绍 介绍实习项目、难点、参与的工作 项目用到的设计模式以及其他设计模式 syn锁(升级过程、降级?(读写锁)一些底层原理) 操作系统线程间同步机制 syn和lock区别 线程池、参数详

欢迎您访问我的公众号【前程有光】 3513

建信金科后端笔试复盘:Java基础、数据库与并发编程考点全解析

后端开发岗位的笔试往往不只是考查算法能力,更看重对核心技术栈的理解深度。以Java生态为例,集合源码、JVM内存模型与并发编程是衡量候选人基本功的关键维度;而数据库的事务隔离级别与索引优化,则直接关系到金融级系统的一致性与查询性能。这些原理在实际工程中对应着高并发场景下的线程安全、数据一致性保障和慢SQL治理等核心问题。针对银行系金融科技公司的招聘特点,笔试命题通常围绕Java基础、Spring框架、数据库与微服务组件展开,要求候选人在掌握基础概念的同时,具备将理论迁移到业务场景的能力。本文以建信金科后端岗

weixin_33910385的博客 350

后台开发常问面试题集锦(问题搬运工,文末附问题链接)

Java基础问题 String的'+'的性能及原理 java之yield(),sleep(),wait()区别详解-备忘笔记 深入理解Java Stream流水线 抽象 & abstract关键字 Java final 修饰符知识点总结(必看篇) Java中的static关键字解析 Java 回调机制解读 Java抽象类与oop三大特征 Java时间和时间戳的相互转换...

小码农 TT 1031

java面试知识

java基础面向对象编译与解释并存多线程平台无关性( Java 虚拟机实现平台无关性)垃圾回收机制接口和抽象类的区别JVM内存结构和Java内存模型别再傻傻分不清了JVM(一):JVM内存模型(面试常见考点)华为技术专家居然把JVM内存模型讲解这么细致JAVA常量池,一篇文章就足够入门了。(含图解)JVM中的堆和栈到底存储了什么?写sql数据库相关文章这里8.0的nysql使用groupby语句会出现问题 https://blog.youkuaiyun.com/shell_girl/article/details/10

hwp_ing的博客 419
上一篇: 程序员不想在IT行业发展,对未来很迷茫,接下来该转行吗?
下一篇: 网易Java研发面试官眼中的Java并发——安全性、活跃性、性能
Java_supermanNO1
博客等级 码龄7年 1170粉丝 329原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值