目录
一、线程池定义
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
线程池内部维护了若干线程,没有任务的时候,这些线程都处于等待空闲状态。如果有新的线程任务,则线程池会分配一个空闲线程执行。如果所有线程都处于忙碌状态,线程池会创建一个新线程进行处理或者放入队列(工作队列)中等待。
如图所示:
┌─────┐ execute ┌──────────────────┐
│Task1│─────────>│ThreadPool │
├─────┤ │┌───────┐┌───────┐│
│Task2│ ││Thread1││Thread2││
├─────┤ │└───────┘└───────┘│
│Task3│ │┌───────┐┌───────┐│
├─────┤ ││Thread3││Thread4││
│Task4│ │└───────┘└───────┘│
├─────┤ └──────────────────┘
│Task5│
├─────┤
│Task6│
└─────┘
二、线程池的优点
1.降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2.提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3.提高线程的可管理性。线程是稀缺资源,如果无限的创建,不仅会消耗系统的资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控。
三、线程池的执行流程
1.首先提交一个线程任务,线程池会在线程池中分配一个空闲线程,用于执行线程任务;
2.若线程池不存在空闲线程,则会判断当前“存活的线程数”是否小于核心线程数(corePoolSize)。
(1)若小于,则创建一个核心线程分配给该线程任务;
(2)若大于,线程池会检查工作队列。
3.(1)若工作队列未满,则将该线程任务放入工作队列中等待。线程池中如果出现空闲线程,将从工作队列中按照先进先出(FIFO)的规则取出一个线程任务分配执行。
(2) 若工作队列已满,则判断线程数是否大于最大线程数(maximumPoolSize)。
4.(1)若当前“存活线程数”没有达到最大线程数,则创建一个新线程(非核心线程)执行新线程任务;
(2)若当前“存活线程”已经达到最大线程数,直接采用拒绝策略处理新线程任务。
流程如下:
四、线程池的状态
线程池的状态有五种:RUNNING(运行状态),SHUTDOWN(关闭状态),STOP(停止状态),TIDYING(整理状态),TERMINATED(终止状态)。
RUNNING:运行状态,线程池一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0。该状态的线程池会接受新任务,并处理工作队列中的任务。
(1)调用线程池 shutdown()方法,可以切换到SHUTDOWN关闭状态;
(2)调用线程池的shutdownNow()方法,可以切换到停止STOP状态;
SHUTDOWN:关闭状态,该状态的线程池不会接受新任务,但会处理工作队列中的任务;当工作队列为空时,线程池进入TIDYING状态;
STOP:停止状态,该状态的线程不会接受新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;线程池中的任务为空时,进入TIDYING状态;
TIDYING:整理状态,该状态表明所有任务已经运行终止,记录的任务数量为0;terminated()方法执行完毕,进入TERMINATED状态;
TERMINATED:终止状态,该状态表示线程池彻底关闭。