点击上方“方志朋”,选择“置顶或者星标”

你的关注意义重大!

随着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>corePoolSize则是判断当前线程数是否大于corePoolSize。

②如果当前线程数大于corePoolSize,则会调用workQueue的poll方法获取任务,超时时间是keepAliveTime。如果超过keepAliveTime时长,poll返回了null,上边提到的while循序就会退出,线程也就执行完了。

如果当前线程数小于corePoolSize,则会调用workQueue的take方法阻塞在当前。

作者:清仁

介绍:多年从事互联网开发,以Java后端开发为主,其它为辅。先后在某上市游戏公司做页游服务端开发,也曾在创业公司做移动APP后端架构设计,目前在阿里巴巴从事资深研发的工作。

-更多文章-

spring cloud gateway 之限流篇

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

这就是2018年的我~

如何优雅的使用和理解线程池

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

一个故事讲清楚NIO

现身说法:37岁老码农找工作

-关注我-

线程池的工作原理与源码解读相关推荐

  1. java并发编程——线程池的工作原理与源码解读

    2019独角兽企业重金招聘Python工程师标准>>> 线程池的简单介绍 基于多核CPU的发展,使得多线程开发日趋流行.然而线程的创建和销毁,都涉及到系统调用,比较消耗系统资源,所以 ...

  2. MyBatis 核心对象,工作原理及源码解读

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) Mybatis工作原理 InputStream inputStream = Resources.getResourceAsStream(reso ...

  3. 并发编程之 Executor 线程池原理与源码解读

    并发编程之 Executor 线程池原理与源码解读 线程是调度 CPU 资源的最小单位,线程模型分为 KLT 模型与 ULT 模型,JVM使用的是 KLT 模型.java线程与 OS 线程保持 1:1 ...

  4. 一文读懂线程池的工作原理(故事白话文)

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 前言 本 ...

  5. 全面解读Java线程池的工作原理

    目录 一.为什么引入线程池技术? 二.Executor框架 2.1 Runnable.Callable与Future接口 2.2 Executor接口 2.2.1 Executor 2.2.2 Exe ...

  6. JAVA8线程池THREADPOOLEXECUTOR底层原理及其源码解析

    小侃一下 1. 使用线程池的好处. 为什么要使用线程池? 2. 线程池核心参数介绍 3. 提交任务到线程池中的流程 3.1 ThreadPoolExecutor#execute方法整体流程 3.2 排 ...

  7. 彻底搞懂Java线程池的工作原理

    一.线程池的基础知识 创建线程需要占用一定的操作系统资源,在高并发情况下,频繁的创建和销毁线程会大量消耗CPU和内存资源,对程序性能造成很大的影响.为了避免这一问题,Java提供了线程池(通过线程复用 ...

  8. Java 线程池的工作原理

    文章目录 概念 线程中的基本方法 线程复用 线程池的核心组件和核心类 线程池的工作原理 线程池中的workQueue任务队列 直接提交队列(SynchronousQueue) 有界任务队列(Array ...

  9. 深入理解线程池(ThreadPoolExecutor)——细致入微的讲源码。

    在上一篇博文<图解线程池原理>中,大体上介绍了线程池的工作原理. 这一篇从源码层面,细致剖析,文章会很长. 如果上篇文章内容没吸收,先看上篇,先易后难嘛. 本文源码是 java 1.8 版 ...

最新文章

  1. jdbc mysql连接测试_JDBC测试计划-连接mysql
  2. 英雄联盟手游超燃测试服务器维护,《英雄联盟手游》超燃测试放号开启,轻松教你获得测试资格...
  3. .net core3.0上传文件出现404_使用FTP代理功能连接空间上传文件(解决改善用户上传慢的问题)...
  4. tableau可视化数据分析60讲(六)-数据连接及数据混合
  5. 权限管理系统中 管理员能看到所有用户的密码么_计算机毕设项目002之学生成绩管理系统...
  6. List VS Set
  7. 手机整屏显示数据php,完美解决手机网页大背景不能铺完整个屏幕的超级代码
  8. The LLVM Compiler Infrastructure | LLVM编译器基础设施
  9. mac上的mongodb安装与使用的踩坑记
  10. B - Cube HDU - 1220 (数学计数)
  11. linux计算圆周率程序,科学网—[转载]关于Linux中使用bc命令计算圆周率(π):可以计算上千位或上万位,顺便评测CPU的计算能力 - 张成岗的博文...
  12. 牛客网 二叉搜索树与双向链表
  13. 16.看板方法---三类改进机会
  14. c#定时器Timer
  15. 五笔打字--思成五笔秘方
  16. linux内存映射对开发版刷屏,TQ6410/OK6410裸机LCD刷屏程序借助UBOOT来执行
  17. 小学计算机社团团长职责,社团团长小学作文
  18. oracle.jdbc.driver.OracleDriver is deprecated
  19. .fire勒索病毒如何删除 .fire后缀文件恢复(Dharma)
  20. Redis INCR命令

热门文章

  1. BZOJ1251: 序列终结者
  2. WannaCry的UWP版,哈哈哈
  3. shell下的作业管理(转)
  4. bzoj 3262 陌上花开
  5. 编写高质量代码改善C#程序的157个建议——建议148:不重复代码
  6. Google搜索的常用技巧
  7. 资料分享:送你一本《数据结构(C#语言版)》电子书!
  8. Analysis and Design Overview
  9. LeetCode刷题-3
  10. 赠书 | GNN 模型在生物化学和医疗健康中的典型应用