- 使⽤场景:假设⼀个服务器完成⼀项任务所需时间为:T1-创建线程时间,T2-在线程中执⾏任务的时间,T3-销毁线程时间。如果T1+T3远⼤于T2,则可以使⽤线程池,以提⾼服务器性能;
- 组成:
- 线程池管理器(ThreadPool):⽤于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
- ⼯作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执⾏任务;
- 任务接⼝(Task):每个任务必须实现的接⼝,以供⼯作线程调度任务的执⾏,它主要规定了任务的⼊⼝,任务执⾏完后的收尾⼯作,任务的执⾏状态等;
- 任务队列(taskQueue):⽤于存放没有处理的任务。提供⼀种缓冲机制。
- 原理:线程池技术正是关注如何缩短或调整T1,T3时间的技术,从⽽提⾼服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者⼀些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
- ⼯作流程:
- 线程池刚创建时,⾥⾯没有⼀个线程(也可以设置参数prestartAllCoreThreads启动预期数量主线程)。任务队列是作为参数传进来的。不过,就算队列⾥⾯有任务,线程池也不会⻢上执⾏它们。
- 当调⽤ execute() ⽅法添加⼀个任务时,线程池会做如下判断:
- 如果正在运⾏的线程数量⼩于 corePoolSize,那么⻢上创建线程运⾏这个任务;
- 如果正在运⾏的线程数量⼤于或等于 corePoolSize,那么将这个任务放⼊队列;
- 如果这时候队列满了,⽽且正在运⾏的线程数量⼩于 maximumPoolSize,那么还是要创建⾮核⼼线程⽴刻运⾏这个任务;
- 如果队列满了,⽽且正在运⾏的线程数量⼤于或等于 maximumPoolSize,那么线程池会抛出异常RejectExecutionException。
- 当⼀个线程完成任务时,它会从队列中取下⼀个任务来执⾏。
- 当⼀个线程⽆事可做,超过⼀定的时间(keepAliveTime)时,线程池会判断,如果当前运⾏的线程数⼤于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的⼤⼩。