说明
在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。
简单说说线程池的创建
?
public ThreadPoolExecutor(int corePoolSize, // 核心线程数量
int maximumPoolSize, // 允许创建的最大线程数量
long keepAliveTime, // 线程存活时间
TimeUnit unit, // 线程存活单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler)
corePoolSize: 指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去;
maximumPoolSize: 指定了线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量;
keepAliveTime: 当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;
unit: keepAliveTime的单位
workQueue: 任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;
threadFactory: 线程工厂,用于创建线程,一般用默认即可;
handler: 拒绝策略;当任务太多来不及处理时,如何拒绝任务;
额外参数: allowCoreThreadTimeout 允许核心线程超时
如果 maximumPoolSize ,workQueue 这2个参数都有效的话,线程池中存在的容量最大为totalTask = workQueue的容量 + maximumPoolSize
前提: 线程池的工作线程都不是空闲的,按顺序来哦
1.如果当前线程数量 < corePoolSize ,新的任务后创建新的线程进行工作
2.如果当前线程的数量 >= corePoolSize , 新的任务会进入缓存队列
3.如果缓存队列已经满了 , 新的任务 会 继续创建新的线程执行
4.如果线程数量(看做一个任务一个线程)直到线程数量超过 maximumPoolSize 时执行拒接策略
你没有猜错:假设 corePoolSize = 10 , QueueCapacity = 3 ,maximumPoolSize = 14
这时候:
?
如果你有18个任务,你第18个任务会触发拒绝策略
如果你刚好又14个任务:
前10个核心线程在执行任务
第11个 - 13个 在队列中
第14个就会创建新的线程去执行(你第14个会比第11个 - 13 个先执行哦)
?