线程池状态
RUNNING:初始化状态是RUNNING.。线程池一单被创建,就处于RUNNING状态,并且线程池中的任务书为0。RUNNING状态下,能接受新的任务,以及对已经添加的任务进行处理。
SHUTDOWN:SHUTDOWN状态时,不接受新的任务,但能处理已经添加的任务。代用线程池的shutdown()接口时,线程池有RUNNING->SHUTDOWN。
STOP:不接受新任务,不处理已经添加的任务,并且中断正在处理的任务。调用线程池的shutdownNow()接口时,线程池有(RUNNING或者SHUTDOWN)->STOP
TIDYING:所有的任务都已终止,队列中的“任务数量”为0,线程池会变成TIDYING。线程池变为TIDYING状态时,会执行投资函数terminated(),可以通过重载terminated()函数来实现自定义行为。
TERMINATED:线程池处于TIDYING状态时,执行完terminated()之后,就会有TIDYING->TERMINATED
结构说明
查看源码可得知,线程池当中有两个集合。一个queue和一个hashset
//存放任务的队列
private final BlockingQueue<Runnable> workQueue;
//存放线程
private final HashSet<Worker> workers = new HashSet<Worker>();
/**
* 核心线程数
*/
private volatile int corePoolSize;
/**
* 最大线程数
*/
private volatile int maximumPoolSize;
任务提交
- 添加任务时,如果线程池中的线程数没有达到corePoolSize,则创建新的线程执行该任务。
- 如果已经达到corePoolSize,就将任务放入workQueue。
- 如果workQueue已经放满,线程数量没有达到maximumPoolSize,则创建线程执行该任务。
- 如果已经达到maximumPoolSize,则执行拒绝策略reject。
- 超时后线程被释放,下降到corePoolSize
注意点
线程如何保证不被销毁?
如果队列中没有任务,核心线程会一直阻塞在take(),知道返回任务,而执行完任务又会进入下一轮的take()方法。如果不是核心线程,进入获取任务方法时会执行poll(long timeout, TimeUnit unit),等待一段时间去过去,获取不到直接返回,runWorker中如果获取的任务为null时会执行processWorkerExit销毁线程。
线程池中的线程会处于什么状态?
TIMED_WAITING,RUNNABLE,WAITING.
核心线程和非核心线程有区别吗?
没有,和线程的创建前后也没有关系,主要看当一个线程没有任务执行时,线程池中的现有线程数,如果大于核心线程数,那此线程就是非核心线程,如果小于核心线程数,那么此线程就是核心线程。