Java线程池类型介绍

JDK的线程池相信大家都有用过,它预先创建好一部分线程,使用完后放回池中,避免了创建与销毁线程的昂贵开销,使得性能大大提升,和数据库连接池是一样的道理,本文简单介绍一下java中的几种线程池。

jdk提供了Executors类方便我们创建线程池,我们平时都是使用它的静态方法newxxxxThreadPool进行线程池的创建。1.8中一共提供了5种线程池。
在这里插入图片描述

1.固定数量的线程池

在这里插入图片描述
这个比较好理解,即线程的数量是固定的,线程并不会随着任务的多少而变化。可以发现他最终是通过实例化ThreadPoolExecutor来实现。ThreadPoolExecutor的构造函数有很多参数,每个参数代表的含义是需要了解的,他决定了ThreadPoolExecutor的行为,我们来看一下他的参数最多的构造函数。

参数最多构造函数:

后俩个参数为默认值的构造函数:

默认拒绝策略:

corePoolSize:线程池的核心线程数量

maximumPoolSize:线程池中允许的最大线程数

keepAliveTime:当池中线程数大于核心线程数时,该时间为余下线程(存活线程总数-核心线程数)的最大空闲存活时间

unit:时间单位

workQueue:工作队列,存放将要执行的任务的地方

threadFactory:创建线程的线程工厂

handler:达到线程上限或者队列容量上限时执行的拒绝策略。

这里需要说明一下线程池的执行行为。当核心线程未满时新来任务会创建核心线程,当corePoolSize满了以后,任务会进入阻塞队列,只有当阻塞队列满了以后,才会创建非核心线程,当最大线程数与队列均满了以后,才会执行拒绝策略。所以这里就有一个问题,假如你希望你配置的maximumPoolSize能够生效,那么workQueue一定不可以是无界队列(关于队列部分会再写一篇文章)。

我们接着分析FixedThreadPool,通过构造函数我们可以发现,corePoolSize=maximumPoolSize,工作队列为LinkedBlockingQueue并且没有指定容量,即最大容量为Integer.MAX_VALUE。使用的线程工厂为默认,使用的拒绝策略也为默认。拒绝策略这里也顺便说一下,jdk提供了4种拒绝策略。

在这里插入图片描述
AbortPolicy:这个比较简单粗暴,直接抛出异常,也是默认的拒绝策略。

CallerRunsPolicy:直接在调用线程中执行该任务。

DiscardPolicy:直接将该任务丢弃。

DiscardOldestPolicy:丢弃最老的未被执行的任务,并重复入队操作

2.并行线程池

在这里插入图片描述
这个是1.8中新加入的线程池,可以看到主要使用了ForkJoin相关的操作,ForkJoin本人没有使用过,也比较复杂,这里就不说了(因为不会)。

3.只有一个线程的线程池

在这里插入图片描述
其实这个可以不称为线程池,因为只有一个线程。核心线程=最大线程=1,这个比较适合需要保证队列中任务顺序执行的场景。

4.缓存线程池

在这里插入图片描述
他根据需要创建线程,没有核心线程,当60s内没有任务时,将会回收存活的线程,60s内有任务时,他可以重用已有的线程。注意他的工作队列是SynchronousQueue,这里简单的说一下),他的每一个put操作必须等待take操作,这意味着如果任务生产速度大于消费速度,那么他将不会创建新线程。该线程池适合执行大量小任务的场景。

5.延时线程池

在这里插入图片描述
ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,所以super最终会调到ThreadPoolExecutor的构造函数,可以看到,最大线程数为int最大值,工作队列为延时队列DelayedWorkQueue,该线程池适合执行延时任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值