一、线程池作用
- 降低资源消耗;提高线程利用率,降低创建和销毁线程的消耗。
- 提高响应速度;任务来了,直接有线程可用可执行,而不需要先创建线程,在执行。
- 提高线程的可管理性;线程是稀缺资源,使用线程池可以统一分配调优监控。
二、线程池核心参数
- corePoolSize :代表核心线程数,也就是正常情况下创建的工作线程数,这些线程创建后并不会销毁,而是会常驻;
- maxinumPoolSize:代表的是最大线程数,它与核心线程数相对应,表示最大允许创建的线程数,比如任务较多,将核心线程数都用完了,仍然无法满足需求时,此时就会继续创建新的线程,但是线程池内线程总数不会超过最大线程数;
- keepAliveTime:表示超出核心线程数之外的线程的空闲时间,也就是说核心线程不会消除,但是超出核心线程数的部分线程如果空闲一定时间则会销毁,我们可以通过设置keepAliveTime来控制空闲时间;
- unit:表示空闲时间的单位
- workQueue:用来存放待执行的任务,假设我们现自核心线程都被使用了,还有任务进来则全部放入等待队列中,直到等待队列放满任务还再继续加入新任务则会创建新的新的线程;
- ThreadFactory:实际上是一个线程工厂,用来生产线程执行任务。我们可以选择使用默认的创建工厂,生产的线程在同一个组内,拥有相同的优先级,且都不是守护线程。当然我们也可以根据业务需要选择自定义线程工厂;
- Handler:任务拒绝策略,有两种情况,第一种时当我们调用shutdown等方法关闭线程池后,这时候即使线程池内部还有未执行完成的任务,但是由于线程池已经关闭,我们再继续向线程池提交任务就会遭到拒绝。另外一种情况时当达到最大线程数,线程池已经没有能力继续处理新提交的任务时,这是也就是拒绝
三、线程池处理流程
四、线程池中阻塞队列的作用
一般的队列只能保证作为一个有限长度的缓冲区,如果超出了缓冲长度,就无法保留当前任务了,阻塞队列通过阻塞可以保留住当前想要继续入队的任务。
阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。
阻塞队列自带的阻塞和唤醒功能,不需要额外处理,无任务时,线程池利用阻塞队列的take方法挂起,从而维持核心线程的存活,不至于一直占用cpu资源。
五、为什么当核心线程数已满时,是先添加队列,而不是先创建临时线程
在创建新线程的时候,时要获取全局锁的,这个时候其他线程就得被阻塞,影响了线程的整体执行效率。而将任务添加到队列缓冲,很好的避免了临时线程的创建销毁开销。
举例说明,一个企业里面有10个(core)正式员工的名额,最多招收10个正式工,要是任务超过了正式工的数量(task>core)的情况下,工厂领导(线程池)不是首先扩招工人,还是10个人,允许任务稍微积压一下(放到队列中)。10个正式工慢慢干,迟早会干完的,要是任务还在继续增加,超过正式工的加班忍耐极限了(队列已满),这时就不得不招收外包员工了,要是加上外包值后,还是不能及时完成的任务,就会被领导拒绝了(执行拒绝策略)