theme: channing-cyan
highlight: androidstudio

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」

文章目录

    • theme: channing-cyan highlight: androidstudio
  • 前言
  • 源码实例
    • corePoolSize
    • maximumPoolSize
    • keepAliveTime
    • unit
    • workQueue
    • threadFactory
    • handler
  • 总结

前言

凌晨的时候说了一下那个线程池的有关七个参数,那么这里完整的大致说一下,这个其实是一个面试题。

源码实例

我们随便搞了这个

public class Pools {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);executorService.execute(new MyThread());executorService.execute(new MyThread());executorService.execute(new MyThread());executorService.shutdownNow();//用完要关}
}class MyThread implements Runnable{@Overridepublic void run() {System.out.println("FUcking");}
}

现在点进去看 newFixedThreadPool 的实现

创建线程池的方法实现了 ThreadPoolExecutor 方法。

从源码中可以看出,线程池的构造函数有7个参数,分别是 corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler

那么接下来分别说说这七个参数。

corePoolSize

线程池核心线程大小

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。

maximumPoolSize

线程池最大线程数量

一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

keepAliveTime

空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定

unit

keepAliveTime的计量单位

TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小时
TimeUnit.MINUTES;           //分钟
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //纳秒

workQueue

工作队列

新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:

  • ArrayBlockingQueue 有界队列

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

  • LinkedBlockingQuene 无界队列

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

  • SynchronousQuene 直接提交

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

  • PriorityBlockingQueue 优先级队列

具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue和SynchronousQueue。

线程池的排队策略与BlockingQueue有关 (可查看线程池 newScheduledThreadPool 的创建方式)。

threadFactory

用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程做些更有意义的事情,比如 设定线程名、设置daemon和优先级等等

handler

拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:

  • CallerRunsPolicy 只用调用者所在线程来运行任务

该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。

  • AbortPolicy 直接抛出异常

该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。

  • DiscardPolicy 不处理,丢弃掉

该策略下,直接丢弃任务,什么都不做。

  • DiscardOldestPolicy 丢弃队列里最近的一个任务,并执行当前任务

该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列

  • 也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。

总结

这个就是关于七大参数的解释,其实很好理解。那么关于java多线程这块的review就先这样,后面再聊聊JUC。

ThreadPoolExecutor 线程池的七个参数相关推荐

  1. 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略

    目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...

  2. ThreadPoolExecutor线程池核心参数详解

    理解ThreadPoolExecutor线程池的corePoolSize.maximumPoolSize和poolSize 我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为 ...

  3. ThreadPoolExecutor线程池使用及参数详解

    先贴一段实际应用代码,应用场景是一个基于http请求拦截的用户行为分析数据录入片段: package com.howbuy.coop.interceptor;import java.sql.Times ...

  4. 创建线程池的七种方式

    在 Java 语言中,并发编程往往都是通过床架线程池来实现的,而线程池的创建方式也有很多种,每种线程池的创建方式都对应了不同的使用场景.总结来说线程池的创建可以分为两大类: 通过 Executors ...

  5. Java多线程学习总结(4)——ThreadPoolExecutor 线程池的拒绝策略学习总结

    前言 谈到java的线程池最熟悉的莫过于ExecutorService接口了,jdk1.5新增的java.util.concurrent包下的这个api,大大的简化了多线程代码的开发.而不论你用Fix ...

  6. 【多线程】线程池的创建和参数设定

    为什么要使用线程池 在日常开发中为了提高代码运行效率,或多或少会用线程去执行异步任务,线程的创建和销毁是需要占用一定资源的. 首先我们看一下一个线程的创建步骤: 为线程堆栈分配和初始化大量内存块 需要 ...

  7. Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】

    基于JDK1.8详细介绍了ThreadPoolExecutor线程池的execute方法源码! 上一篇文章中,我们介绍了:Java Executor源码解析(2)-ThreadPoolExecutor ...

  8. ThreadPoolExecutor线程池原理

    ThreadPoolExecutor线程池原理 线程池原理 1. 线程池的简单介绍 1.1 线程池是什么 1.2 线程池解决的核心问题是什么 2. 线程池的实现原理 2.1 线程池的执行流程 2.2 ...

  9. ThreadPoolExecutor线程池,shutdown和shutdownNow关闭线程池方式对比,以及确保线程池能够彻底关闭的一种方式

    1. ThreadPoolExecutor线程池 1.1 创建线程池,构造方法的几个参数说明及创建如下. 1.2 shutdown方式关闭线程池 a. 空闲且能interrupt表示该线程处于阻塞等待 ...

最新文章

  1. Linux下cat命令各种用法
  2. iOS 开发和部署过程概述
  3. 在Pandas DataFrame中重塑数据
  4. 20-spring学习-Spring MVC基本操作
  5. go 自定义error怎么判断是否相等_「GCTT 出品」Go 系列教程——30. 错误处理
  6. github克隆仓库加速
  7. 如何把竖排的数据变为横排_读懂微信改版背后的焦虑,企业新媒体营销该如何自救?...
  8. 读过的设计模式的书小结
  9. Google 正式发布 Fuchsia OS,Flutter 集成尚存问题
  10. 分享一个强大的工具,可以快速查看自己公司网站或竞争对手网站的CDN情况
  11. pb9.0.3 8836补丁包_英语单数/复数名词傻傻分不清楚?3种不规则形态一次性搞懂!...
  12. 基于反步法backstepping的自适应控制简介
  13. 电子学会2022年12月青少年软件编程(图形化)等级考试试卷(一级)答案解析
  14. 13 个优秀的 Vue 开源项目及合集推荐
  15. word中表格出现无法自动换页问题
  16. 煤矿用计算机,计算机技术在煤矿安全生产中应用
  17. Clothoid回旋曲线在APA路径优化中的工程应用实例及其C++源码分析与下载
  18. swiper 滚回第一个数据_分散能源数据的区块链应用
  19. codechef November Challenge 2017解题报告
  20. Qt QByteArray字节数组

热门文章

  1. 几个不错的extjs的blog
  2. 哪怕荆棘满路,我们仍无畏前行
  3. 你真的会用搜索引擎吗?能写出好论文、找到好工作的那种
  4. Python个人主页项目-3.个人数据后端管理应用开发
  5. python-数据分析-pandas基础知识
  6. html中图片不溢出,防止图片过大超出DIV的CSS样式
  7. NOI / 小学奥数——7826:分苹果
  8. 2022数维杯问题 C:如何利用大脑结构特征和认知行为特征诊断阿尔茨海默病-多思路+代码分享
  9. 向右看齐Look Up
  10. ros ur5模拟扫描