专栏首页吉林乌拉ThreadPoolExecutor的使用

ThreadPoolExecutor的使用

ThreadPoolExecutor也就是线程池。它就是Java为我们开发多线程程序时提供的一个开发框架。它可以统一的管理线程的创建、销毁、优化、监控等,在使用线程池时比我们直接使用原始的线程类更加方便。既然线程池这么方便,那它到底是怎么实现上述的功能呢?下面我们先看一下当用线程池启动一个线程时它的流程图。

线程池的处理流程如下:

当我们用线程池启动一个任务时,线程池首先会检查核心线程池里面的线程数是否已经超过corePoolSize。如果没有超过则创建一个新的线程执行任务。如果超过了,那么将当前执行的任务添加到线程池的工作队列中,但在加入之前会先检查工作队列是否已经满了,如果工作队列已经满了,那么此时它会检查线程池中的线程是否超过了允许的最大数量。如果没有超过则创建线程执行任务,如果超过了最大数量,则按照无法执行的策略处理。

线程池的创建:在创建ThreadPoolExecutor时,会需要传递几个必要的参数,下面我们详细看一下它们每个参数所代表的含义。

  • corePoolSize(初始化的空闲线程):当我们创建ThreadPoolExecutor对象时,可以用corePoolSize参数设置线程池的初始化线程数,也就是空闲线程,当线程池中的线程数量小于corePoolSize时,线程池会重新创建一个新的线程来处理任务,而不是直接使用线程池中的空闲线程。
  • maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。也就最大并发数,也就是说线程池允许多少个线程同时执行。
  • keepAliveTime(线程活动保持时间):当线程池中的线程数大于corePoolSize时,用此参数设置空闲线程等待新任务的时间。在此时间内如果线程没有接收到新的任务,那么当前线程会被销毁。
  • TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS)、小时(HOURS)、分钟(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和纳秒(NANOSECONDS,千分之一微秒)。
  • BlockingQueue(线程池中的任务队列),当线程池中线程数大于corePoolSize时,新提交的任务会被保存到任务队列中。在线程池中主要有4种不同的任务队列。
  1. ArrayBlockingQueue:是基于数组结构的任务队列。此队列按先进先出的原则对任务进行排序。
  2. LinkedBlockingQueue:是基于链表结构的任务队列。此队列也是按先进先出的原则对任务进行排序。但性能通常要比ArrayBlockingQueue高
  3. SynchronousQueue:一个不存储元素的任务队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
  4. PriorityBlockingQueue:是一个具有优先级的任务队列。此队列中的元素必须能够比较。
  • ThreadFactory():创建线程的线程工厂。
  • RejectedExecutionHandler(饱和策略 ):当线程池中的线程数大于maximumPoolSize时,线程池就不能在处理任何任务了,这时线程池会抛出异常。原因就是这个策略默认情况下是AbortPolicy:表示无法处理新任务时抛出异常。除此之外还有其它几种策略:
  1. AbortPolicy:直接抛出异常。
  2. CallerRunsPolicy:只用调用者所在线程来运行任务。
  3. DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
  4. DiscardPolicy:不处理,丢弃掉。

下面我们用具体的代码来详细说明一下ThreadPoolExecutor的使用。

按照上面的分析,因为我们创建ThreadPoolExecutor对象时初始化的空闲线程是2个,并且我们添加到线程池中的数量也是2个,所以当前任务是由核心线程池执行的任务并不会将任务添加到对列中。如果我在继续向线程池中提交任务,那么因为超过了我们设置的corePoolSize数量,所以此时队列中就有了我们新提交的任务了。

因为我们设置的线程池的最大线程数是3也就是maximumPoolSize的值。如果超过这个值,并且我们没有更改相应的饱和策略,那么此时就会抛出异常信息。

我们发现程序居然没有报错,这是因为什么呢。这是因为参数maximumPoolSize的作是指线程池最大能允许的最大并发数是3也就是说同时可以执行3个线程,但是我们别忘了线程池中还有一个队列呢。队列里存储的就是将要被执行的任务,只是现在已经超过了最大并发数所以队列里的任务只能等待线程池中有其它任务执行完后,它才可以执行。所以此时线程池中允许我们提交任务的最大数就是maximumPoolSize加上队列的数量。但如果我们继续向线程池有添加任务,那么线程池就会报错了,因为已经没有地方存储新任务了,队列也已经满了,所以只能走饱和策略的默认策略就是抛出异常。

下面我们修改一下线程池的饱和策略。

线程池中相关方法的介绍

taskCount:线程池需要执行的任务数。虽然我们向线程池中提交了5个任务,但第5个任务并不是由线程池执行的,是我们修改了饱和策略自己执行的。所以此值返回结果是4。

completedTaskCount:线程池中完成的任务数。

largestPoolSize:线程池中曾经创建过的最大线程数。也就是有多少个线程同是执行,也叫最大并发数。

getPoolSize:线程池中的线程数。如果线程池不销毁,那么线程池里的线程也不会自动销毁。

getActiveCount:活动的线程数。

本文分享自微信公众号 - 吉林乌拉(jilinwulacom)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

推荐阅读

  • 远程办公经验为0,如何将日常工作平滑过度到线上?

    我是一名创业者,我的公司(深圳市友浩达科技有限公司)在2018年8月8日开始运营,现在还属于微型公司。这个春节假期,我一直十分关注疫情动向,也非常关心其对公司带来的影响。

    TVP官方团队
    TAPD 敏捷项目管理腾讯乐享企业邮箱企业编程算法
  • 数据中台,概念炒作还是另有奇效? | TVP思享

    作者简介:史凯,花名凯哥,腾讯云最具价值专家TVP,ThoughtWorks数据智能业务总经理。投身于企业数字化转型工作近20年。2000年初,在IBM 研发企业级中间件,接着加入埃森哲,为大型企业提供信息化架构规划,设计,ERP,云平台,数据仓库构建等技术咨询实施服务,随后在EMC负责企业应用转型业务,为企业提供云迁移,应用现代化服务。现在专注于企业智能化转型领域,是数据驱动的数字化转型的行业布道者,数据中台的推广者,精益数据创新体系的创始人,2019年荣获全球Data IQ 100人的数据赋能者称号,创业邦卓越生态聚合赋能官TOP 5。2019年度数字化转型专家奖。打造了行业第一个数据创新的数字化转型卡牌和工作坊。创建了精益数据创新方法论体系构建数据驱动的智能企业,并在多个企业验证成功,正在向国内外推广。

    TVP官方团队
    大数据数据分析企业
  • 扩展 Kubernetes 之 CRI

    使用 cri-containerd 的调用流程更为简洁, 省去了上面的调用流程的 1,2 两步

    王磊-AI基础
    Kubernetes
  • 扩展 Kubernetes 之 Kubectl Plugin

    kubectl 功能非常强大, 常见的命令使用方式可以参考 kubectl --help,或者这篇文章

    王磊-AI基础
    Kubernetes
  • 多种登录方式定量性能测试方案

    最近接到到一个测试任务,某服务提供了两种登录方式:1、账号密码登录;2、手机号+验证码登录。要对这两种登录按照一定的比例进行压测。

    八音弦
    测试服务 WeTest
  • 线程安全类在性能测试中应用

    首先验证接口参数签名是否正确,然后加锁去判断订单信息和状态,处理用户增添VIP时间事务,成功之后释放锁。锁是针对用户和订单的分布式锁,使用方案是用的redis。

    八音弦
    安全编程算法
  • 使用CDN(jsdelivr) 优化博客访问速度

    PS: 此篇文章适用于 使用 Github pages 或者 coding pages 的朋友,其他博客也类似.

    IFONLY@CUIT
    CDNGitGitHub开源
  • 扩展 Kubernetes 之 CNI

    Network Configuration 是 CNI 输入参数中最重要当部分, 可以存储在磁盘上

    王磊-AI基础
    Kubernetes
  • 聚焦【技术应变力】云加社区沙龙online重磅上线!

    云加社区结合特殊时期热点,挑选备受关注的音视频流量暴增、线下业务快速转线上、紧急上线防疫IoT应用等话题,邀请众多业界专家,为大家提供连续十一天的干货分享。从视野、预判、应对等多角度,帮助大家全面提升「技术应变力」!

    腾小云
  • 京东购物小程序购物车性能优化实践

    它是小程序开发工具内置的一个可视化监控工具,能够在 OS 级别上实时记录系统资源的使用情况。

    WecTeam
    渲染JavaScripthttps网络安全缓存

扫码关注云+社区

领取腾讯云代金券