一、线程池的工作流程

1、线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。

2. 当调用 execute() 方法添加一个任务时,线程池会做如下判断:

如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;

如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;

如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;

如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会根据拒绝策略来对应处理。

线程池的工作流程;线程池主要参数有哪些?_创建线程

  1. 当一个线程完成任务时,它会从队列中取下一个任务来执行。

4. 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。

二、线程池主要参数有哪些?

线程池的工作流程;线程池主要参数有哪些?_等待队列_02

线程池有七大参数,需要重点关注corePoolSize 、maximumPoolSize 、 workQueue 、handler 这四个。

1. corePoolSize

用来初始化线程池中核心线程数,当线程池中线程数<corePoolSize时,系统默认是添加一个任务才创建一个线程池。当线程数=corePoolSize时,新任务会追加到woreQueue中。

2. maximumPoolSize

maximumPoolSize表示允许的最大线程数=(非核心线程数+核心线程数),当BlockingQueue也满了,但线程池中的总线程数<maximumPoolSize时会再次创建新的线程。

3. keepAliveTime

非核心线程 =(maximumPoolSize - corePoolSize ) ,非核心线程闲置下来不干活最多存活时间。

4. unit

线程池中非核心线程保持存活的时间的单位

TimeUnit.DAYS; 天

TimeUnit.HOURS; 小时

TimeUnit.MINUTES; 分钟

TimeUnit.SECONDS; 秒

TimeUnit.MILLISECONDS; 毫秒

TimeUnit.MICROSECONDS; 微秒

TimeUnit.NANOSECONDS; 纳秒

5. workQueue

线程池等待队列,维护着等待执行的Runnable 对象。当运行当线程数=corePoolSize时,新的任务会被添加到workQueue 中,如果workQueue 也满了则尝试用非核心线程执行任务,等待队列应该尽量用有界的。

6. threadFactory

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

7. handler

corePoolSize 、workQueue 、maximumPoolSize 都不可用的时候执行的饱和策略。