七叶笔记 » golang编程 » 线程池源码浅析

线程池源码浅析

面试的时候往往会问到 线程池 相关的内容,对于线程池知其然而不知其所以然。本篇文章通过源码阐述线程池构造方法、详细参数信息(核心线程数量、最大线程数量、空闲等待时间、线程工厂、拒绝策略)及线程池的使用。

这是一个手撕实现线程池的视频:

本 Chat 读者将获得以下知识:

  1. 线程池简介
  2. 线程池优点
  3. 线程池构造
  4. 线程池详细参数信息
  5. 使用 Executors 构造线程池的方法及对比
  6. 使用线程池默认构造方法创建线程池
  7. 线程池状态描述
  8. 线程池常用方法解析
  9. 线程池监控常用方法

适合人群: c++Linux开发者

  • 认识线程池
  • corePoolSize
  • maximumPoolSize
  • keepAliveTime
  • threadFactory
  • rejectedExecutionHandler
  • 创建线程池 newFixedThreadPool
  • newSingleThreadExecutor
  • newCachedThreadPool
  • newScheduledThreadPool
  • 线程池状态
  • 常用方法线
  • 程池监控

认识线程池

线程池是什么?线程池就是存放一定量线程的容器,当有待执行任务的时候直接从线程池中取出线程执行任务,任务执行完成之后将线程回放至线程池中。

线程池的优点:降低了线程频繁创建、销毁的开销,提高系统的响应速度,方便统一管理创建的线程。

线程池( ThreadPoolExecutor )提供 4 个默认的构造方法,固定参数 5 个。如下图:

详细参数解释如下:

  • 核心线程数量:corePoolSize
  • 最大线程数量:maximumPoolSize
  • 非核心线程空闲等待时间:keepAliveTime
  • 等待时间单位:timeUnit
  • 等待阻塞队列:blockingQueue<Runnable>
  • (可选)线程工厂创建线程:threadFactory
  • (可选)线程池拒绝策略:rejectedExecutionHandler

corePoolSize

线程池中默认存活的线程数量。不同的线程池对于核心线程数量有不同的要求,也与 allowCoreThreadTimeout 参数有关。

当 allowCoreThreadTimeout= true 时,核心线程没有任务且存活时间超过空闲等待时间后终止。

maximumPoolSize

线程池中允许的最大线程数量。

当 currentThreadNumber >= corePoolSize,且任务队列已满时,线程池会创建新线程来处理任务;当 currentThreadNumber =maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常。

keepAliveTime

线程池中空闲线程允许存活的时间,超过配置时间将会被终止。

  • blockingQueue :线程池缓存队列存放待处理的线程任务。
  • ArrayBlockingQueue :指定大小的等待队列(FIFO);有界队列,创建时需要指定队列的大小。
  • LinkedBlockingQueue :基于链表的等待队列(FIFO);无界队列,创建时不指定队列大小,默认为 Integer.MAX_VALUE。
  • PriorityBlockingQueue :带有优先级的等待队列
  • SynchronizedQueue :不存放对象的等待队列;同步移交队列,直接新建一个线程来执行新来的任务。

threadFactory

线程工厂,创建线程使用。

rejectedExecutionHandler

当线程池的任务缓存队列已满并且线程池中的线程数目达到 maximumPoolSize 时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

  • AbortPolicy (默认策略):丢弃任务并抛出 RejectedExecutionException
  • CallerRunsPolicy :只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
  • DiscardOldestPolicy :丢弃队列中最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务(舍弃最老的请求,即将队列头部任务舍弃)。
  • DiscardPolicy :不做任何处理,直接丢弃任务。

创建线程池

线程池的创建主要有 2 种方式:基于 ThreadPoolExecutor 的构造方法创建和 Executors 执行器创建。Executors 执行器创建线程池是在 ThreadPoolExecutor 构造方法上进行简单的封装,特殊场景根据需要自行创建。

文末给大家分享c/c++ Linux服务器高阶知识视频资料的朋友请后台私信【架构】获取

知识点有C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB, ZK ,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。

相关文章