Java多线程系列——线程池原理之 ThreadPoolExecutor

ThreadPoolExecutor 简介

ThreadPoolExecutor 是线程池类。

通俗的讲,它是一个存放一定数量线程的线程集合。线程池允许多个线程同时运行,同时运行的线程数量就是这个线程池的容量,也会有一部分线程出现阻塞,线程池此时也会通过响应的拒绝策略来处理。

构造函数参数说明

  • corePoolSize:池中所保存的线程数,包括空闲线程
  • maximumPoolSize:池中允许的最大线程数
  • keepAliveTime:当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
  • unit:keepAliveTime 参数的时间单位
  • workQueue:执行前用于保持任务的队列(被提交但尚未执行的任务)。此队列仅保存由 execute 方法提交的 Runable 任务
  • threadFactory:执行程序创建新线程时使用的工厂
  • handler:拒绝策略,由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序

corePoolSize  与 maximumPoolSize 的关系

如果运行线程数少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队;

如果运行的线程大于等于 corePoolSize,则 Executor 始终首选将请求加入阻塞队列,而不添加新的线程;

如果无法将请求加入队列,则创建新的线程,如果创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝;

如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。如果将 maximumPoolSize 设置为基本的无界值(Integer.MAX_VALUE),则允许池适应任意数量的并发任务,直到内存耗尽。在大都数情况下,核心池大小和最大池大小在创建线程池时设置,不过也可以通过 setCorePoolSize() 和 setMaximumPoolSize() 进行动态更改。

ThreadPoolExecutor 的数据结构

  • workers:workers 为 HashSet<Worker> 类型。一个 Worker 对应一个线程,线程池通过 workers 包含了多个线程。当线程池启动时,它会执行线程池中的任务,执行完后,它会从线程池的阻塞队列中取出阻塞任务来执行。线程池通过它实现了“允许多线程同时运行”
  • workQueue:workQueue 为 BlockingQueue<Runnable> 阻塞队列类型。当线程池中的线程数超过它的容量时,线程会进入阻塞队列进行阻塞等待。线程池通过它实现了线程阻塞功能
  • mainLock:Condition 类型,通过它实现了线程池的互斥访问
  • corePoolSize:核心池大小
  • maximumPoolSize:最大池大小
  • poolSize:当前线程池的实际大小,即线程池中的任务数量

线程池通过 workers 集合来管理多线程,线程启动后,就会执行对应的任务。任务执行完毕后,它会从阻塞队列中取出任务继续执行。阻塞队列负责管理线程池来不及处理的任务,当添加线程池被添加到最大线程池大小时,就会执行拒绝策略(handler),来处理当前提交但被拒绝的任务。

原文地址:https://www.cnblogs.com/zhengbin/p/7750177.html