线程池是什么?
线程池是多线程开发中关键技术之一,线程池能够提高系统性能,是为了优化直接创建线程产生的问题而存在的组件。
线程池解决了什么问题?
1.创建/销毁线程伴随着系统开销,频繁的创建/销毁线程,会很大程度上影响处理效率
线程无法复用就会频繁的创建销毁线程,给系统带来不必要的开销。
2.线程并发数量过多,抢占系统资源从而导致阻塞
当线程并发数量没有受到限制,可能会对系统造成过大压力。
3.对线程进行一些简单的管理
统一对线程别名、定时运行等功能进行管理
ThreadPoolExecutor线程池参数组成
在ThreadPoolExecutor覆写字段最全的构造方法中,可以看到以下参数:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:非核心线程外其它线程空闲情况下存活时间
unit:keepAliveTime的基本时间单位
workQuene:线程工作队列
threadFactory:线程创建工厂
handler:拒绝策略处理器
ok,依次来解释以上参数的含义:
corePoolSize是指线程池核心线程的数量,可以理解为系统中复用线程数的阀值,核心线程是不会被销毁的。
maximumPoolSize是指系统中最多能同时存在的线程数量,超过这个数量也不会再创建线程给予调度。
keepAliveTime和unit是指超过核心线程数之后创建的非核心线程存活时间,这个数值决定多久回收非核心线程
workQuene是指线程池中的任务队列:维护着等待执行的runnable等对象
threadFacotry是指线程创建工厂,线程的创建都是通过factory工厂,所以这里一般会进行别名等处理
handler是指当超过线程池负载量的时候采取的策略。
结合这个图来看一下线程池的具体流程:
一开始主线程fork子线程的请求,直接会创建出核心线程给予调度,直到所有的核心线程都正在调度还没有完成task的时候,这个时候如果再有fork请求,此时已经没有可用的核心线程,那么就会丢往workQuene里面等待调度,如果workQuene满了,而最大线程数如果大于核心线程数,此时会继续创建线程给予调度,直到最大线程数也满了,触发拒绝策略进行丢弃或者日志等处理。
在以上过程中,每次创建线程都经threadFactory处理,且队列选择有多种,队列长度也分为有界与无界,结合以上流程,可分析出不同的配置项最终会怎样影响线程池的效果。
ok,讲到这里,看一下线程池创建方式有哪些:
1.jdk原生线程池:也就是自己去创建ThreadPoolExecutor
2.jdk工具类:也就是Executors工具类,这里包含四五种实现方式。
3.spring、tomcat等开源线程池
以上的创建方式,笔者都在项目之中使用过,这三种方式最终都是通过ThreadPoolExecutor来创建,总结下来,现在不推荐使用Executors工具类的方式生成线程池,由于fix池没有队列长度限制,而cache池对于最大线程数没有限制。所以这两种常见的使用方式都有一定的内存或cpu隐患。
下一篇博客分享具体使用案例。