Java线程池

ThreadPoolExecutor

在Java中可以创建的线程池类有很多,各自拥有不同的特性,但查看源码可以发现,这些线程池的创建在底层都调用了new ThreadPoolExecutor(),因此我们首先讨论ThreadPoolExecutor。

1 public ThreadPoolExecutor(int corePoolSize,
2                               int maximumPoolSize,
3                               long keepAliveTime,
4                               TimeUnit unit,
5                               BlockingQueue<Runnable> workQueue,
6                               ThreadFactory threadFactory,
7                               RejectedExecutionHandler handler)
参数类型 参数名 含义
int corePoolSize 核心线程数量
int maximumPoolSize 最大线程数量
long keepAliveTime 线程最大空闲时间
TimeUnit unit 存活时间的计量单位
BlockingQueue<Runnable> workQueue 用于存放Runnable任务的阻塞队列
ThreadFactory threadFactory 线程创建工厂
RejectedExecutionHandler handler 拒绝策略

线程池创建后,初始线程数量为0,通过调用execute(Runnable command)来创建线程对象执行任务。

 

创建任务主要流程

1.判断线程池中线程的数量是否小于corePoolSize,如果小于则创建一个新的线程执行任务,否则进行下一步判断。

2.判断workQueue中是否还有空间存放Runnable任务,如果有则加入workQueue,否则进行下一步判断。

3.判断线程池中线程的数量是否小于maximumPoolSize,如果小于则创建一个新的线程执行任务,否则执行拒绝策略。

第2步和第3步判断前会先判断是否有空闲线程,有的话直接交给空闲线程(不确定)。而线程空闲后也会主动执行workQueue中的任务。

当线程池中的一个线程空闲时间超过了keepAliveTime,会判断线程池中线程的数量是否大于corePoolSize,如果大于的话,该线程会被销毁,否则不会。

 

了解了ThreadPoolExecutor后,就可以根据不同线程池类底层调用构造方法的参数,去判断这些线程池的特性。

 

CachedThreadPool

1 public static ExecutorService newCachedThreadPool() {
2         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
3                                       60L, TimeUnit.SECONDS,
4                                       new SynchronousQueue<Runnable>());
5     }

从以上参数可以看到,核心线程数量为0,因此进入第2步,如果没有空闲线程,应加入阻塞队列,而SynchronousQueue是一种特殊的没有容量的阻塞队列,因此进入第3步,如果没有空闲线程,则创建一个新的线程执行任务,由于maximumPoolSize为Integer.MAXVALUE,因此可以理解为是“无限”容量的线程池。

当线程空闲时间超过60秒时,会被销毁。

特点:不会有长时间存放的空闲的核心线程,没有等待的概念,有线程就用,没线程就创建,可创建“无限”数量的线程。

 

FixedThreadPool

1 public static ExecutorService newFixedThreadPool(int nThreads) {
2         return new ThreadPoolExecutor(nThreads, nThreads,
3                                       0L, TimeUnit.MILLISECONDS,
4                                       new LinkedBlockingQueue<Runnable>());
5     }

从以上参数可以看到,核心线程数量和最大线程数量都是指定的n,LinkedBlockingQueue又是无界阻塞队列,所以当线程数量小于n时,优先创建线程,当线程数量等于n时,如果此时没有空闲线程,所有任务都会进入阻塞队列,只能等待空闲线程来执行。

线程最大空闲时间是0毫秒,实际没有影响,因为最大线程数量等于核心线程数量,而核心线程又是不会被销毁的,所以一旦线程数量达到n,就不会再创建也不会再销毁。

特点:线程数量最多只会等于n,并且达到n后不会再创建和销毁,没有线程执行时,所有任务都会进入无界阻塞队列等待执行。

 

posted @ 2020-09-08 15:50  昆梧  阅读(191)  评论(0)    收藏  举报