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),来处理当前提交但被拒绝的任务。
梦想要一步步来!