一. ThreadPoolExecutor的构造参数

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
TimeUnit unit, BlockingQueue<runnable> workQueue,
ThreadFactory threadFactory,RejectedExecutionHandler handler)


​ThreadPoolExecutor​​一共有7个参数,下面是每个参数的意义

参数名

类型

说明

corePoolSize

int

核心线程数

maximumPoolSize

int

线程池中最大线程数

keepAliveTime

long

除核心线程外,其他线程空闲时间,

配置了allowCoreThreadTimeOut之后

该属性也可作用于很线程

unit

TimeUnit

和keepAliveTime搭配使用

workQueue

BlockingQueue

工作队列

threadFactory

ThreadFactory

线程创建工厂

handler

RejectedExecutionHandler

线程池拒绝策略

二. corePoolSize和maximumPoolSize

corePoolSize和maximumPoolSize这两个参数使用来控制线程池大小的参数,​​ThreadPoolExecutor​​会根据这两个参数的值来动态的调整线程池的大小,将这两个属性的值设置成一样,就会得到一个固定大小的线程池。​​ThreadPoolExecutor​​在接受一个任务时主要分为三个步骤,如下图。


graph LR Start(Submit Task)-->core{"WorkSize>corePollSize"} core--是-->queue{"WorkQueue is full"} queue--是-->maxpool{"WorkSize>maxPoolSize"} maxpool--是-->Reject core--否-->new("Execute Task ") queue--否-->addToQueue("addToQueue ") maxpool--否-->newTask("Execute Task ")


  1. 通过​​public void execute(Runnable command)​​方法来提交一个一个任务
  2. 判断当前工作线程数是否大于核心线程数,否则创建一个新的线程执行该任务
  3. 如果大于当前核心线程则尝试放入工作队列中进行等待
  4. 如果工作队列已满,则判断工作线程数是否大于最大线程数,是则根据​​RejectedExecutionHandler​​拒绝该任务,否则创建一个新的线程执行该任务

总结上面的流程我们可以看出,线程池方式的优点:

  1. 合理控制并发的线程数,将执行的工作线程数控制在核心线程数,合理利用系统资源
  2. 合理管理线程的创建和销毁,我们知道线程的创建是十分消耗系统资源的,而通过线程池的方式,可以不必频繁的创建线程,可以利用线程池中空闲的线程资源来执行任务。在系统空闲线程不够的情况下才会去创建新的线程,这样在密集任务执行时可以合理利用线程资源。在默认情况下,只有新任务进来时,才会去创建核心线程,不过你可以通过​​public boolean prestartCoreThread()​​和​​public int prestartAllCoreThreads()​​去创建一个或所有核心线程。

三. JDK内置的集中线程池

在​​java.util.concurrent.Executors​​中​​JAVA​​已经为我们实现好了集中常用的线程池.。

  1. FixedThreadPool创建一个固定线程数的线程池,其实就是将ThreadPollExecutor的核心线程数和最大线程数两个属性设置成一样的值,可以用来控制并发数.
    public static ExecutorService newFixedThreadPool(int nThreads); public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
  2. CachedThreadPool创建一个可缓存的线程池,在收到一个任务时,会在空闲的线程中去一个出来执行任务,如果没有则会创建一个新的线程去执行任务,适合短期的大量的异步任务。CachedThreadPool的核心线程数设置的为0,每次都是从工作队列中去执行任务,代码中设置的超时时间是60秒,这样在超过60秒之后,空闲的线程就会被回收,不会出现占用系统资源的情况。
    public static ExecutorService newCachedThreadPool(); public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
  3. SingleThreadExecutor创建一个只有一个工作线程的线程池,线程池中只有一个线程去执行任务,可以控制任务的顺序性。
    public static ExecutorService newSingleThreadExecutor(); public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);
  4. SingleThreadScheduledExecutor创建只有一个工作线程的可执行周期性任务的线程池,它除了可以像其他的线程池一样可以执行异步任务,也支持执行定时任务。
    public static ScheduledExecutorService newSingleThreadScheduledExecutor(); public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);