线程池状态

线程池shutdown重新启动 线程池shutdown原理_创建线程


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;

任务提交

  1. 添加任务时,如果线程池中的线程数没有达到corePoolSize,则创建新的线程执行该任务。
  2. 如果已经达到corePoolSize,就将任务放入workQueue。
  3. 如果workQueue已经放满,线程数量没有达到maximumPoolSize,则创建线程执行该任务。
  4. 如果已经达到maximumPoolSize,则执行拒绝策略reject。
  5. 超时后线程被释放,下降到corePoolSize

注意点

线程如何保证不被销毁?

如果队列中没有任务,核心线程会一直阻塞在take(),知道返回任务,而执行完任务又会进入下一轮的take()方法。如果不是核心线程,进入获取任务方法时会执行poll(long timeout, TimeUnit unit),等待一段时间去过去,获取不到直接返回,runWorker中如果获取的任务为null时会执行processWorkerExit销毁线程。

线程池中的线程会处于什么状态?

TIMED_WAITING,RUNNABLE,WAITING.

核心线程和非核心线程有区别吗?

没有,和线程的创建前后也没有关系,主要看当一个线程没有任务执行时,线程池中的现有线程数,如果大于核心线程数,那此线程就是非核心线程,如果小于核心线程数,那么此线程就是核心线程。