查看ThreadPoolExecutor的源码发现,其提供了4个构造方法,如下:
其中典型使用
线程池会根据corePoolSize和maximumPoolSize自动地调整线程池大小
- 如果当前线程池的线程数少于corePoolSize线程正在运行的个数时, 无论已有线程是否空闲,都会新增一个线程
- 如果当前线程池的线程大于或者是等于corePooleSIze,并且任务队列没有满时,将其提交给阻塞队列排队
- 如果线程池的大于或者等于corePoolSize,并且任务队列满时
如果当前线程池的线程 < maximumPoolSize,则新增线程
如果当前线程池的线程 = maximumPoolSize, 拒绝新增任何,可通过拒绝策略来进行控制
任务执行过程:
1. 提交新的任务时,判断,是否达到了核心线程数量,如果达到,则创建一个工作线程来执行任务
2. 判断工作队列是否已经满了, 如果没满,则将新提交的任务存储在工作队列中
3. 判断是否达到了线程最大数量,如果没有达到, 则创建一个新的工作线程来执行
4. 通过拒绝策略来处理任务
Executors常用工具类:
- newFixedThreadPool(int nThreads): 固定大小,任务队列容量无界的线程池.corePoolSize=maximumPoolSize。
- newCachedThreadPool(): 适用于执行耗时较小的异步任务,大小无界的缓冲线程池,是一个同步队列,keepAliveTime为60秒,corePoolSize为0,maximumPoolSize为Integer.MAX_VALUE
- newSingleThreadExecutor():只有一个线程来执行无界任务队列的单一线程池,与newFixedThreadPool(1)
的区别在于,单一线程池的池大小在newSingleThreadExecutor方法中硬编码,不能改变 - newScheduledThreadPool(int corePoolSize) 定时执行任务的线程池。corePoolSize由参数指定,最大线程数为Integer.MAX_VALUE
如何确定合适数量的线程:
计算型任务:cpu数量的1-2倍
IO型任务: 比计算型任务多一些线程,具体需要IO阻塞时长进行考量决定,可以考虑根据需要,在一个最小数量和最大数量间进行自动增减线程数