【Java】线程池七大参数

这篇具有很好参考价值的文章主要介绍了【Java】线程池七大参数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、核心线程数(corePoolSize):

线程池中的基本线程数量

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

二、最大线程数(maximumPoolSize):

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

三、空闲线程存活时间(keepAliveTime):

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

四、空闲线程存活时间单位(unit )

keepAliveTime的计量单位,也就是空闲线程的存活时间单位

五、工作队列(workQueue ):

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

①ArrayBlockingQueue

数组型阻塞队列,基于数组有界阻塞队列,按FIFO(先进先出策略)排序。

使用一个重入锁ReentrantLock),默认使用非公平锁,入队和出队共用一个锁,互斥。

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

②LinkedBlockingQuene

链表型阻塞队列,基于链表有界(近似无界)阻塞队列,默认初始化大小为Integer.MAX_VALUE(其实最大容量为Interger.MAX),按照FIFO先进先出策略)排序。

使用一个重入锁ReentrantLock),默认使用非公平锁,入队和出队共用一个锁,互斥。

由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

③SynchronousQuene

同步移交队列。容量为0,添加任务必须等待取出任务,这个队列相当于通道,不存储元素。

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

④PriorityBlockingQueue

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

put 的时候会tryGrow,要说它有界也没问题,因为界是 Integer.MAX_VALUE,但其实上这个队列应该是无界的。默认采用元素自然顺序升序排列(可以自定义Comparator)。

使用一个重入锁分别控制元素的入队和出队。

⑤DelayQueue

延时队列。无界,队列中的元素有过期时间,过期的元素才能被取出。使用一个重入锁分别控制元素的入队和出队,用 Condition 进行线程间的唤醒和等待。任务调度时候可以使用。

六、线程工厂(threadFactory):

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等

七、任务拒绝策略(handler):

当线程池线程数已满,并且工作队列达到限制,新提交的任务使用拒绝策略处理。可以自定义拒绝策略,拒绝策略需要实现 RejectedExecutionHandler 接口,有四种策略(1)抛异常、(2)丢弃任务不抛异常、(3)打回任务、(4)尝试与最老的线程竞争。

默认拒绝策略是 AbortPolicy

  • AbortPolicy:丢弃任务并抛出 RejectedExecutionException 异常
  • DiscardPolicy:丢弃任务,但是不抛出异常。可能导致无法发现系统的异常状态
  • DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
  • CallerRunsPolicy:由调用线程处理该任务

①CallerRunsPolicy

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

功能:当触发拒绝策略时,只要线程池没有关闭,就由提交任务的当前线程处理。

使用场景:一般在不允许失败的、对性能要求不高、并发量较小的场景下使用,因为线程池一般情况下不会关闭,也就是提交的任务一定会被运行,但是由于是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能和效率自然就慢了。

②AbortPolicy(线程池默认策略)

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

功能:当触发拒绝策略时,直接抛出拒绝执行的异常,中止策略的意思也就是打断当前执行流程

使用场景:这个就没有特殊的场景了,但是一点要正确处理抛出的异常。ThreadPoolExecutor中默认的策略就是AbortPolicyExecutorService接口的系列ThreadPoolExecutor因为都没有显示的设置拒绝策略,所以默认的都是这个。但是请注意,ExecutorService中的线程池实例队列都是无界的,也就是说把内存撑爆了都不会触发拒绝策略。当自己自定义线程池实例时,使用这个策略一定要处理好触发策略时抛的异常,因为他会打断当前的执行流程。

③DiscardPolicy

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

功能:直接静悄悄的丢弃这个任务,不触发任何动作

使用场景:如果你提交的任务无关紧要,你就可以使用它 。因为它就是个空实现,会悄无声息的吞噬你的的任务。所以这个策略基本上不用了

④DiscardOldestPolicy

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

功能:如果线程池未关闭,就弹出队列头部的元素,然后尝试执行

使用场景:这个策略还是会丢弃任务,丢弃时也是毫无声息,但是特点是丢弃的是老的未执行的任务,而且是待执行优先级较高的任务。基于这个特性,我能想到的场景就是,发布消息,和修改消息,当消息发布出去后,还未执行,此时更新的消息又来了,这个时候未执行的消息的版本比现在提交的消息版本要低就可以被丢弃了。因为队列中还有可能存在消息版本更低的消息会排队执行,所以在真正处理消息的时候一定要做好消息的版本比较。文章来源地址https://www.toymoban.com/news/detail-684809.html

到了这里,关于【Java】线程池七大参数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】JDK8 jvm参数配置及说明

    -Xms 或 -XX:InitialHeapSize=n 设置堆的初始值 指令1:-Xms2g 指令2:-XX:InitialHeapSize=2048m -Xmx 或 -XX:MaxHeapSize=n 设置堆区最大值 指令1: -Xmx2g 指令2: -XX:MaxHeapSize=2048m -XX:NewSize=n 设置年轻代大小 -Xss 或 -XX:ThreadStackSize=n 每个线程堆栈最大值 指令1:-Xss256k 指令2:-XX:ThreadStackSize=256k 注意:

    2024年02月03日
    浏览(53)
  • JAVA HEAP SPACE解决方法和JVM参数设置

    JAVA HEAP SPACE解决方法和JVM参数设置 JAVA HEAP SPACE解决方法和JVM参数设置 原因分析 设置 异常分析 Java堆的管理—垃圾回收提到一下几点,很不错,或许可以作为写程序时候的准则: jvm 内存查看与分析工具 在JVM中如果98%的时间是用于GC(Garbage Collection)且可用的 Heap size 不足2%的时

    2024年02月06日
    浏览(49)
  • Java 线程池 参数

    线程池能有效管控线程,统一分配任务,优化资源使用。 创建线程池,在构造一个新的线程池时,必须满足下面的条件: corePoolSize(线程池基本大小) 必须大于或等于0; maximumPoolSize(线程池最大大小) 必须大于或等于1; maximumPoolSize必须大于或等于corePoolSize; keepAliveTim

    2024年04月10日
    浏览(27)
  • [Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args

    一次没搞懂,处处受影响。这个问题属于基础问题,但又经常踩坑,不得不重视一下了。 IDEA中的配置位置 参数 使用方式 示例 代码获取方式 系统属性 由操作系统、JVM、应用程序主动设置 System.setProperties(Properties propes) / System.setProperties(String key,String value) / System.getProperties(

    2024年02月08日
    浏览(42)
  • 线程方法接收参数和返回参数,Java的两种线程实现方式对比

    总所周知,Java实现多线程有两种方式,分别是继承Thread类和实现Runable接口,那么它们的区别是什么? 继承 Thread 类: 通过继承 Thread 类,你可以创建一个直接表示线程的类。你可以覆盖 Thread 类中的 run 方法来定义线程的逻辑。当调用 start 方法启动线程时,会执行该类中的

    2024年02月11日
    浏览(45)
  • 在Maven中设置JVM系统参数及Java应用调试实例

    在进行Java应用程序开发时,我们通常需要配置Maven构建过程中Java虚拟机(JVM)的额外系统参数,以便进行性能优化、日志配置或远程调试等操作。本文将详细介绍如何在Maven中设置JVM系统参数,并通过一个具体的Java应用远程调试示例来演示这一过程。 Maven使用环境变量 MAVE

    2024年01月23日
    浏览(44)
  • Java多线程之线程池的参数和配置

    在Java多线程编程中,线程池是一种常见的技术,用于管理线程的创建和销毁。线程池中的线程可以被重复利用,从而减少了线程的创建和销毁的开销,提高了程序的性能。在Java中,线程池的参数和配置非常重要,不同的参数和配置会影响线程池的性能和行为。 Java线程池的主

    2024年02月16日
    浏览(39)
  • 线程方法接收参数示例,Java的两种线程实现方式区别

    总所周知,Java实现多线程有两种方式,分别是继承Thread类和实现Runable接口,那么它们的区别是什么? 继承 Thread 类: 通过继承 Thread 类,你可以创建一个直接表示线程的类。你可以覆盖 Thread 类中的 run 方法来定义线程的逻辑。当调用 start 方法启动线程时,会执行该类中的

    2024年02月11日
    浏览(43)
  • java语法(二)线程并发、Juit单元测试、反射机制、注解、动态代理、XML解析、JVM

    正则表达式验证网站 1、 ? :表示前边这个字符可以出现0次或者1次。例如下边 /used? 既可以匹配 use 也可以匹配 used 。 2、 * :匹配0个或者多个字符, * 号代表前边这个字符可以出现0次或者多次。例如 /ab*c 可以匹配 ac、abc、abbbbc 3、 + :与 * 号不同的是, + 需要前面这个字符

    2024年02月06日
    浏览(53)
  • TOMCAT部署及优化(Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

    TOMCAT tomcat :是一个开放源代码的web应用服务器,基于java代码开发的。也可以理解为tomacat就是处理动态请求和基于java代码的页面开发。可以在html当中写入java代码,tomcat可以解析html页面当中的java,执行动态请求,动态页面。 tomcat是机制存在一些问题,如果不对tomcat进行优化

    2024年02月13日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包