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:活动的线程数。

threadpoolexecutor参数_ThreadPoolExecutor的使用相关推荐

  1. ThreadPoolExecutor参数解析

    一.ThreadPoolExecutor的重要参数 1)corePoolSize:核心线程数 核心线程会一直存活,及时没有任务需要执行 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线 ...

  2. Java线程池ThreadPoolExecutor参数讲解、实例助记 保证你过目不忘

    ThreadPoolExecutor构造器的参数说明 参数一:指定线程池的核心线程数量(核心线程,长久不死亡): corePoolSize 不能小于0 参数二:指定线程池可支持的最大线程数: maxi ...

  3. Tomcat网络IO NIO模型参数设定

    2019独角兽企业重金招聘Python工程师标准>>> 1 默认IO模型 1.1 配置项的解析 Tomcat 7.0.35 的配置文件是$CATALINA_HOME/conf/ser ...

  4. 高并发中,那些不得不说的线程池与ThreadPoolExecutor类

    摘要:从整体上认识下线程池中最核心的类之一--ThreadPoolExecutor,关于ThreadPoolExecutor的底层原理和源码实现,以及线程池中的其他技术细节的底层原理和源码实现. 本文 ...

  5. 为什么阿里不允许用Executors创建线程池,而是通过ThreadPoolExecutor的方式?

    1.通过Executors创建线程池的弊端 在创建线程池的时候,大部分人还是会选择使用Executors去创建. 下面是创建定长线程池(FixedThreadPool)的一个例子,严格来说,当使用如下 ...

  6. 为什么阿里巴巴禁止使用 Executors 创建线程池,而是通过 ThreadPoolExecutor 方式?...

    >>号外:关注"Java精选"公众号,菜单栏->聚合->干货分享,回复关键词领取视频资料.开源项目. 1. 通过Executors创建线程池的弊端 在创建线 ...

  7. 线程池的几个重要参数

    线程池 - ThreadPoolExecutor 参数 corePoolSize :核心线程数量 maximumPoolSize :线程最大线程数 workQueue :阻塞队列,存储等待执行的任务 ...

  8. JAVA8线程池THREADPOOLEXECUTOR底层原理及其源码解析

    小侃一下 1. 使用线程池的好处. 为什么要使用线程池? 2. 线程池核心参数介绍 3. 提交任务到线程池中的流程 3.1 ThreadPoolExecutor#execute方法整体流程 3.2 排 ...

  9. 面试官:说一下线程池内部工作原理?

    以下文章来源方志朋的博客,回复"666"获面试宝典 作者:清泉 cnblogs.com/qingquanzi/p/8146638.html 随着cpu核数越来越多,不可避免的利用多 ...

最新文章

  1. 烧脑:宇宙时空结构是量子纠错码
  2. 虚拟现实技术的发展和分类
  3. [转]PowerDesigner使用教程 —— 概念数据模型
  4. QDialog常用理解
  5. 循环神经网络_小孩都看得懂的循环神经网络
  6. java 全角半角符号转换_java 字符串全角半角转换
  7. WPF 媒体播放器(MediaElement)实例,实现进度和音量控制
  8. 自定义 View 实现汉字笔顺动画
  9. OSx86的来龙去脉
  10. 计算机主机和音箱的接口电路,Zigbee协议与USB主机无线音箱电路设计
  11. python ddos攻击器
  12. python嗅探器_Python中的简单原始数据包嗅探器
  13. UE4 设置Play下的默认相机FOV(Field Of View)视角
  14. 嵌入式学习为什么要选择4412开发板
  15. uniapp页面跳转时showToast不显示
  16. java isreachable_java-奇数InetAddress.isReachable()问题
  17. 罗杨美慧 20190919-2 功能测试
  18. 数学之美-隐马尔科夫模型
  19. java 策略模式 促销_设计模式之策略模式
  20. UGUI内核大探究(十八)Raycaster

热门文章

  1. eclipse导入工程报错解决
  2. 读《纸本书变电子书是很小的事》有感
  3. 使用cisco 2500路由器实现ADSL接入
  4. 计算二个日期经过几月又几天
  5. 如何跳过或去除“非正版Windows系统“信息
  6. 面试官系统精讲Java源码及大厂真题 - 04 Arrays、Collections、Objects 常用方法源码解析
  7. 容器编排技术 -- Kubernetes kubectl 概述
  8. Dubbo面试 - 如何自己设计一个类似 Dubbo 的 RPC 框架?
  9. github推荐好玩项目
  10. windows10中屏幕键盘 vs 触摸键盘