Java线程池工具类Executors

前文介绍到我们可以通过创建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异常。


原文始发于微信公众号(小海编码日记):Java线程池工具类Executors

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/67784.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!