线程池简析

2020-05-13  本文已影响0人  tandeneck

使用线程池好处

ThreadPoolExecutor

ThreadPoolExecutor 是线程池的真正实现,它的构造方法提供了一系列参数来配置线程池,如下:

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

核心池的大小,在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了 prestartAllCoreThreads() 或者 prestartCoreThread,从这 2 个 方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建 corePoolSize 个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为 0,当有任务来之后,就会创建一个核心线程去执行任务,当线程池的线程数目达到 corePoolSize 后,就会把要到达的任务放到缓存队列当中。

maxumumPoolSize

线程池所能容纳的最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程。

keepAliveTime

表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于 corePoolSize 时,keepAliveTime 才会起作用,直到线程池中的线程数不大于 corePoolSize,即当线程池中的线程数大于 corePoolSize 时,如果一个线程大于 corePoolSize 时,如果一个线程空闲的时候达到 keepAliveTime,则会终止,直到线程池中的线程数不超过 corePoolSize。但是如果调用了 allowCoreThreadTimeOut(boolean)方法,在线程池中的线程池不大于 corePoolSize 时,keepAliveTime 参数也会起作用,直到线程池的线程数为 0。

unit

用于指定 keepAliveTime 参数的时间单位,这是一个枚举,常用的有 TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)以及 TimeUnit.MINUTES(分钟)等。

workQueue:

一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响。

threadFactory

线程工厂,主要用来创建线程。

handler

表示当拒绝处理任务时的策略,有以下四种取值:

ThreadPoolExecutor 执行任务的大概流程:
  1. 如果当前运行的线程,少于 corePoolSize,则创建一个新的线程来执行任务。
  2. 如果运行的线程等于或多于 corePoolSize,则将任务加入 BlockingQueue。
  3. 如果加入 BlockingQueue 成功,需要检查线程池的状态,如果线程池的状态没有在 running,则从 BlockQueue 移除任务,启动拒绝策略。
  4. 如果线程池加入 BlockQueue 失败,则创建新的线程来处理任务
  5. 如果启动线程数大于 maximumPoolSize,任务将被拒绝策略拒绝。
  6. 如果非核心线程空闲时间大于 keepAliveTime,则销毁。
上一篇下一篇

猜你喜欢

热点阅读