zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java线程池工具类Executors

JAVA工具线程 executors
2023-06-13 09:17:14 时间

前文介绍到我们可以通过创建ThreadPoolExecutor对象来定制属于自己的线程池,在创建一个线程池时需要关注核心线程数,最大线程数,拒绝策略,线程构造工厂,任何队列等7个参数,相对而言,灵活度偏高,初次使用的开发者在参数设计和处理时,可能会有困惑,所以java.util.oncurrent并发工具包中也为我们提供了快捷创建线程池的工具类,用于创建常见模版线程,这个类叫做Executors

Executors

Executors中提供的函数及说明如下表所示:

函数名

说明

备注

defaultThreadFactory()

返回一个默认的线程工厂,在其内部创建的线程是优先级为Thread.NORM_PRIORITY的非守护线程,线程会被命名为pool-N-thread-M,N代表的是第几个线程工厂,M代表这个工厂生产的第几个线程

/

newCachedThreadPool()

创建一个线程重用的线程池,在该线程池中当任务提交时,会重用已经创建的线程,如果没有线程可用,才会创建新线程,最多可以创建Integer.MAX_VALUE个线程,超过60秒未使用的线程将会被终止并从缓存中移除。通常用于处理时间短,请求密集的场景

/

newCachedThreadPool(ThreadFactory threadFactory)

使用指定线程工厂创建缓存线程池,其他细节与newCachedThreadPool()相同

/

newFixedThreadPool(int nThreads)

创建一个固定容量的线程池,这个线程池的核心线程数=最大线程数=nThreads,也就意味着同时最多有nThreads个线程运行,如果有线程在被关闭前,执行失败终止了,后续有任务需要执行时,会创建一个新的线程,在未主动调用shutdown前,这些线程会一直存在。

/

newFixedThreadPool(int nThreads, ThreadFactory threadFactory)

使用指定线程数和线程工厂创建一个固定容量的线程池,线程池特性和newFixedThreadPool(int nThreads)相同

/

newScheduledThreadPool(int corePoolSize)

使用corePoolSize为核心线程数,创建一个可以定时或周期性执行任务的线程池,

/

newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)

使用corePoolSize为核心线程数,threadFactory为线程工厂,创建一个可以定时或周期性执行任务的线程池

/

newSingleThreadExecutor()

创建一个单线程运作的线程池,在该线程池上顺序按照顺序执行,在任意给定时间,最多一个任务在执行

/

newSingleThreadExecutor(ThreadFactory threadFactory)

使用指定的线程工厂创建一个单线程线程池,线程池特性同newSingleThreadExecutor()创建的线程池

/

newSingleThreadScheduledExecutor()

创建一个可以定时或周期性执行任务的单线程池

/

newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

使用指定线程工厂创建一个可以定时或周期性执行任务的单线程池

/

newWorkStealingPool()

创建一个新的具有抢占式操作的线程池,每个线程都有一个任务队列存放任务。其是对ForkJoinPool的扩展,当不传入参数时,默认创建等于处理器个数的线程数

大家都知道现在多数设备都是多核处理器,在任务处理过程中,如果单个任务耗时过长则其他核的CPU会处于闲置状态,造成浪费。ForkJoinPool主要是出于充分利用多核CPU特性而构造的线程池,针对一个执行时间较长的任务而言,我们可以将其拆分成若干个子任务,这些子任务分别在CPU的每个核上运行,最后将运行结果整合在一起输出返回

newWorkStealingPool(int parallelism)

使用参数parallelism的取值创建一个线程池,线程池特性同newWorkStealingPool(),不同的是线程数是parallelism个

/

结合上表,我们可以看出Executors中一共为我们提供了四类常用线程池,主要有:

  1. 1. CachedThreadPool:缓存线程池
  2. 2. FixedThreadPool:固定容量线程池
  3. 3. SingleThreadPool:单线程线程池
  4. 4. ScheduledThreadPool:周期或定时执行任务的线程池

这些线程池的特性和优缺点如下表所示:

线程池名称

核心线程数

最大线程数

任务队列数据结构/最大长度

缺点

优点

CachedThreadPool

0

Integer.MAX_VALUE

SynchronousQueue

有可能创建太多线程,导致OOM异常

用于执行大量耗时较少的任务

FixedThreadPool

nThreads(最小取值为1,最大取值为Integer.MAX_VALUE)

nThreads

LinkedBlockingQueue/Integer.MAX_VALUE

有可能任务队列中积攒过多任务,引起OOM异常

线程数量固定,能够更好的响应外界任务请求

SingleThreadPool

1

1

LinkedBlockingQueue/Integer.MAX_VALUE

同上

顺序执行任务

ScheduledThreadPool

corePoolSize(最小取值为0,最大取值Integer.MAX_VALUE)

Integer.MAX_VALUE

DelayedWorkQueue

有可能创建太多线程,导致OOM异常

用于处理定期/定时任务

从上表可以看出,对于Executors提供的模版函数构建的线程池而言,由于其等待队列或者最大线程数为Integer.MAX_VALUE,使得其均有OOM异常的风险,故在使用时,应考虑详尽,规避大量任务或线程的创建,如果遇到相关异常,建议使用ThreadPoolExecutor自行实现线程池,限制线程池的线程或任务数量,以避免OOM异常。