基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
说一下线程池内部工作原理
说一下线程池内部工作原理
阅读
1
2020-01-06
随着
cpu
核数越来越多,不可避免的利用多线程技术以充分利用其计算能力。所以,多线程技术是服务端开发人员必须掌握的技术。
线程的创建和销毁,都涉及到系统调用,比较消耗系统资源,所以就引入了线程池技术,避免频繁的线程创建和销毁。
在
Java
中有一个
Executors
工具类,可以为我们创建一个线程池,其本质就是
new
了一个
ThreadPoolExecutor
对象。线程池几乎也是面试必考问题。本节结合源代码,说说
ThreadExecutor
的工作原理
一、线程池创建
先看一下
ThreadPoolExecutor
参数最全的构造方法:
corePoolSize
:线程池的核心线程数,说白了就是,即便是线程池里没有任何任务,也会有
corePoolSize
个线程在候着等任务。
maximumPoolSize
:最大线程数,不管你提交多少任务,线程池里最多工作线程数就是
maximumPoolSize
。
keepAliveTime
:线程的存活时间。当线程池里的线程数大于
corePoolSize
时,如果等了
keepAliveTime
时长还没有任务可执行,则线程退出。
unit
:这个用来指定
keepAliveTime
的单位,比如秒:
TimeUnit
.
SECONDS
。
workQueue
:一个阻塞队列,提交的任务将会被放到这个队列里。
threadFactory
:线程工厂,用来创建线程,主要是为了给线程起名字,默认工厂的线程名字:
pool
-
1
-
thread
-
3
。
handler
:拒绝策略,当线程池里线程被耗尽,且队列也满了的时候会调用。
以上就是创建线程池时用到的参数,面试中经常会有面试官问到这个问题。
二、线程池执行流程
这里用一个图来说明线程池的执行流程
任务被提交到线程池,会先判断当前线程数量是否小于
corePoolSize
,如果小于则创建线程来执行提交的任务,否则将任务放入
workQueue
队列,如果
workQueue
满了,则判断当前线程数量是否小于
maximumPoolSize
,如果小于则创建线程执行任务,否则就会调用
handler
,以表示线程池拒绝接收任务。
这里以
jdk1
.
8
.
0
_
111
的源代码为例,看一下具体实现。
1、先看一下线程池的executor方法
判断当前活跃线程数是否小于
corePoolSize
,如果小于,则调用
addWorker
创建线程执行任务
如果不小于
corePoolSize
,则将任务添加到
workQueue
队列。
如果放入
workQueue
失败,则创建线程执行任务,如果这时创建线程失败(当前线程数不小于
maximumPoolSize
时),就会调用
reject
(内部调用
handler
)拒绝接受任务。
2、再看下addWorker的方法实现
这块代码是在创建非核心线程时,即
core
等于
false
。判断当前线程数是否大于等于
maximumPoolSize
,如果大于等于则返回
false
,即上边说到的③中创建线程失败的情况。
addWorker
方法的下半部分:
创建
Worker
对象,同时也会实例化一个
Thread
对象。
启动启动这个线程
3、再到Worker里看看其实现
可以看到在创建
Worker
时会调用
threadFactory
来创建一个线程。上边的②中启动一个线程就会触发
Worker
的
run
方法被线程调用。
4、接下来咱们看看runWorker方法的逻辑
线程调用
runWoker
,会
while
循环调用
getTask
方法从
workerQueue
里读取任务,然后执行任务。只要
getTask
方法不返回
null
,此线程就不会退出。
5、最后在看看getTask方法实现
咱们先不管
allowCoreThreadTimeOut
,这个变量默认值是
false
。
wc
&
gt
;
corePoolSize
则是判断当前线程数是否大于
corePoolSize
。
如果当前线程数大于
corePoolSize
,则会调用
workQueue
的
poll
方法获取任务,超时时间是
keepAliveTime
。如果超过
keepAliveTime
时长,
poll
返回了
null
,上边提到的
while
循序就会退出,线程也就执行完了。
如果当前线程数小于
corePoolSize
,则会调用
workQueue
的
take
方法阻塞在当前。
来源:
cnblogs
.
com
/
qingquanzi
/
p
/
8146638
.
html
最近三期
【
37
期】请你详细说说类加载流程,类加载机制及自定义类加载器
【
38
期】一份
tcp
、
http
面试指南,常考点都给你了
【
39
期】
Mybatis
面试
18
问,你想知道的都在这里了!
? ~
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
Mybatis面试18问,你想知道的都在这里了!
下一篇:
盘点那些必问的数据结构算法题之链表
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目