一文搞懂Java自定义线程池参数

article/2025/10/18 11:07:00

背景:

线程是一个开发经常使用的东西,但是实际工作中很少有新建一个线程去执行任务,线程的创建和销毁都会耗费资源,我们一般都会用线程池来完成线程的创建和销毁。

  • 多说一句

JDK自带的线程池不建议大家去使用,每个都存在资源的浪费,甚至会引发OOM问题,大家都是开发,这些东西还是自己根据实际业务去创建自定义的好。

正文

  • 自定义一个线程池首先我们需要知道它怎么去构建,怎么传参,参数都是什么含义,参数传多少合适,接下来一一解开疑惑。
  • 我们首先看一下线程池的构造函数,分析一下里面的参数:

线程池构造函数

  1. CorePoolSize(核心线程数):
    就是我们经常去处理的任务的线程数量,线程池如果没有任务处理时,它们是在空闲状态,不会被销毁,有任务时,它们会直接去处理任务,如果忙不过来就会把任务添加到阻塞队列。

  2. MaximumPoolSize(最大线程数):
    上面说到核心线程来不及去处理任务,线程会放到队列中等待处理。当队列满了,没有办法继续缓存任务时,这个时候线程池会创建一个新线程去处理任务,注意:这里不是处理来的新任务,而是从队列头部拉一个出来,新任务放进去队列里面等待处理,大家都是有顺序的。
    当然这时候队列还是满的,如果任务过来还是会触发这个机制,去建新线程,这个参数就是控制可以创建的最大线程树,如果线程数量超过时,就会触发拒绝策略,下面会将。

  3. keepAliveTime(最大存活时间):
    刚才说了,如果核心线程数都忙着呢,队列也满了,我们就会创建新线程,可是如果线程都执行完任务总不能都去空闲不销毁吧。这时候肯定有一种机制去管理它们,如果空闲线程数大于核心线程数,它们多的线程最多活的时间根据这个参数来设置,到时间了,就会被销毁。

  4. Unit(单位):
    最大存活时间的单位。

  5. workQueue(阻塞队列):
    队列的作用你一定还记得,核心线程忙的时候,任务会放到队列中,JDK提供了4个队列供我们选择

    ArrayBlockingQueue: 基于数组的有边界的队列,按照先进先出排列,跟我们排队一个意思,不能插队。我们创建这个队列的时候,传一个参数就可以了,参数表示队列的容量大小。
    在这里插入图片描述
    LinkedBlockingQuene: 基于链表的阻塞队列,也是采用先进先出,创建时如果构造函数不传队列容量大小时,默认大小为Integer.Max,也可以指定容量大小。
    在这里插入图片描述
    在这里插入图片描述
    SynchronousQueue: 不缓存任务的阻塞队列,任务来了以后不会缓存到队列中,直接创建一个新线程去处理任务。
    在这里插入图片描述
    PriorityBlockingQueue: 是一个支持优先级的无界阻塞队列,直到系统资源耗尽。默认情况下元素采用自然顺序升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。
    在这里插入图片描述

  6. ThreadFactory(线程工厂):
    通过ThreadFactory的newThread方法,可以对创建的线程做一些操控,ThreadFactory是一个接口,我们需要实现它的newThread的方法,这时候我们就可以设置一些线程的参数,这个参数可不填,有默认的。

  7. handler :拒绝策略:
    当队列满了时且线程数达到最大线程数时,这时候任务再来时,就会触发拒绝策略来应对接下来的任务,这时候肯定是资源不够用了,我们需要根据实际场景去选择正确的策略。JDK提供了4钟拒绝策略,我们来看一下每一个策略。
    AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。这是线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,及时反馈程序运行状态。如果是比较关键的业务,推荐使用此拒绝策略,这样子在系统不能承载更大的并发量的时候,能够及时的通过异常发现。
    DiscardPolicy: 丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。
    DiscardOldestPolicy: 丢弃队列最前面的任务,新任务加到队列里面,如果有新任务过来,继续这个策略。
    CallerRunsPolicy: 如果队列满了,这个任务由调用线程去执行。

实战


public static void main(String[] args) {//阻塞队列ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(200);//新建一个自定义线程池ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 50, 30, TimeUnit.SECONDS, arrayBlockingQueue);//循环输出数字for(int i =0;i<200;i++){int num = i;//submit执行方法,也可以用execute,submit具有返回值threadPoolExecutor.submit(new Runnable() {@Overridepublic void run() {try {//让子弹飞一会儿Thread.sleep(1000);//输出线程名System.out.println(num +Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}}});}//线程池使用完一定要关闭threadPoolExecutor.shutdown();}
  • 输出结果
1pool-1-thread-2
2pool-1-thread-3
3pool-1-thread-4
0pool-1-thread-1
4pool-1-thread-5
5pool-1-thread-2
7pool-1-thread-4

注意点

  • 核心线程数多少合适?
    如果是计算性任务,不涉及I/O操作,使用CPU资源比较多,这时候核心线程数和CPU核数相同,
    如果是I/O比较多,比如批量下载文件,读写数据库、redis缓存,这些I/O操作用线程池就可以优化空间很大,我们把核心线程数设置为核数的double(双倍)。

  • 线程池启动方法:
    示例中使用的submit方法,submit方法可以接收Runnable和Callable,Callable可以有返回值,让我们可以知道线程池的执行情况。也可以用execute执行方法,可以启动线程池但是没有返回值。

  • 线程池关闭方法:
    线程池使用完,一定要关闭,这里有两个方法,shutdown()和shutdownNow(),前者是需要等待线程池执行完所有任务在关闭,后者正在执行的任务停止,没有执行的任务返回。


http://chatgpt.dhexx.cn/article/rVgWxK4T.shtml

相关文章

线程池参数调优

ThreadPoolExecutor ThreadPoolExecutor构造函数的五大参数 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, work…

线程池参数和状态详解

线程池详解 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)线程池的构造函数&#xff0c;参数详解&#xff1a;…

Java线程池参数、执行流程及线程数配置建议

1. 线程池参数详解 corePoolSize&#xff1a;线程池中常驻核心线程数&#xff1b;maximumPoolSize&#xff1a;线程池能够容纳同时执行的最大线程数&#xff1b;keepAliveTime&#xff1a;多余的空闲线程存活时间&#xff1b;unit&#xff1a;keepAliveTime的时间单位&#xf…

tomcat线程池参数

tomcat线程池executor配置参数 详解tomcat的连接数与线程池

线程池参数及队列

线程池中各个参数的含义 参数名含义corePoolSize核心线程数maximumPoolSize最大线程数keepAliveTime时间单位空闲线程的存活时间workQueue用于存放任务的队列threadFactory线程工厂、用来创建新线程handler处理别拒绝的任务 corePoolSize是核心线程数&#xff0c;也就是常驻线…

Java线程池参数分析

线程池组成 创建线程池 创建线程池通过Executors的工厂方法来创建线程池实例。 实际上Executors创建的线程池实例最终都是通过实例化配置不同参数的ThreadPoolExecutor对象。 public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecuto…

java线程池参数_java线程池参数设置原则,如何设置线程池参数比较合理?

线程池的参数应该怎样设置呢?相信对于很多的人来说这也是一个比较难的问题&#xff0c;下面就让我们一起来解决一下&#xff0c;究竟应该如何设置线程池的参数才是最合理的吧! 首先在设置参数的时候&#xff0c;有以下的几点是我们需要考虑到的! 1、下游系统抗并发的能力 多线…

线程池参数如何设置?

前言 着计算机行业的飞速发展&#xff0c;摩尔定律逐渐失效&#xff0c;多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池&#xff1a;ThreadPoolExecutor类&#xff0c;帮助开发人员管理线程并方便地执行并行任务。了解并合理…

动态调整线程池参数实践

欢迎大家关注我的微信公众号【老周聊架构】&#xff0c;Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。 一、线程池遇到的挑战 我们上一篇 《一文读懂线程池的实现原理 》已经从线程池如何维护自身状态、线程池如何管理任务、线程…

线程池参数及配置

线程池-线程池参数及配置 在实际项目中线程的应用都会使用线程池来管理&#xff0c;线程池的常用参数及配置学习记录。 目录 线程池-线程池参数及配置 一、线程池 1、线程池的优势 二、线程池常用参数 ThreadPoolExecutor 1. corePoolSize&#xff1a;核心线程数 2. que…

线程池7个参数描述

所谓的线程池的 7 大参数是指&#xff0c;在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数&#xff0c;如以下源码所示&#xff1a; public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable&…

Java线程池七个参数详解

java多线程开发时&#xff0c;常常用到线程池技术&#xff0c;这篇文章是对创建java线程池时的七个参数的详细解释。 从源码中可以看出&#xff0c;线程池的构造函数有7个参数&#xff0c;分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory…

【Android UI】贝塞尔曲线 ② ( 二阶贝塞尔曲线公式 | 三阶贝塞尔曲线及公式 | 高阶贝塞尔曲线 )

文章目录 一、二阶贝塞尔曲线公式二、三阶贝塞尔曲线三、高阶贝塞尔曲线 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一、二阶贝塞尔曲线公式 二阶贝塞尔曲线公式如下 : B ( t ) ( 1 − t ) 2 P 0 2 t ( 1 − t ) P 1 t 2 P 2 , t ∈ [ 0 , 1 ] B(t) (1- t…

浅谈贝塞尔曲线

浅谈贝塞尔曲线 前段时间做了一个手写板功能的东西&#xff0c;其中手写部分用二次贝塞尔曲线完成&#xff0c;今天就来总结一下贝塞尔曲线在Android中的应用&#xff0c;先简单介绍各阶贝塞尔曲线的原理&#xff0c;然后实现通过贝塞尔曲线实现波浪线功能&#xff0c;感兴趣的…

View系列:贝塞尔曲线专栏:绘制二阶贝塞尔曲线(二)

1&#xff1a;Android贝塞尔曲线Api 作用相关Api备注移动起点moveTo移动下一次操作的起点位置连接直线lineTo添加上一个点到当前点的直线Path贝塞尔曲线qyadTo / cubicTo分别为绘制二次和三次贝塞尔曲线的方法闭合路径close从第一个点连接到最后一个点&#xff0c;形成一个闭合…

贝塞尔曲线原理

1 前言 贝塞尔曲线 (Bzier curve) 由法国数学家 Pierre Bzier 于 1962 年提出的一种矢量曲线&#xff0c;广泛应用于工程绘图、动画设计等领域。贝塞尔曲线是一种运动轨迹曲线&#xff0c;由 n 个点在 n 条线段上匀速运动&#xff08;不同线段上的速度可能不同&#xff09;&…

贝塞尔曲线简单介绍

什么是贝塞尔曲线&#xff1f; Bzier curve(贝塞尔曲线) 是应用于二维图形应用程序的数学曲线。 曲线定义&#xff1a;起始点、终止点&#xff08;也称锚点&#xff09;、控制点。通过调整控制点&#xff0c;贝塞尔曲线的形状会发生变化。 1962年&#xff0c;法国数学家Pierre…

贝塞尔曲线原理简述

1. 曲线算法简介&#xff1a; 贝塞尔曲线应用于二维图形应用程序的数学曲线&#xff0c;由一组控制点的向量来确定&#xff0c;给定的控制点按顺序连接构成控制多边形&#xff0c;贝塞尔曲线逼近这个多边形&#xff0c;进而通过调整控制点坐标改变曲线的形状。 2. 绘制曲线 …

贝塞尔曲线动画C++简单实践

目录 贝塞尔曲线简介一阶贝塞尔二阶贝塞尔三阶贝塞尔N阶贝塞尔曲线 贝塞尔曲线在动画中的应用实践求曲线散点坐标将曲线应用到动画动画框架cmd动画窗口动画 完整代码示例代码核心类代码BezierCurveAnimatorConsole 参考资料 贝塞尔曲线简介 由于用计算机画图大部分时间是操作鼠…

贝塞尔曲线及实践案例

文章目录 1. 前言2. 介绍2.1 一阶贝济埃曲线2.2 二阶贝塞尔曲线2.3 三阶贝塞尔曲线 3. 一、二、三阶贝塞尔曲线实现4. 案例5. 后记 1. 前言 贝塞尔曲线(Bzier curve)&#xff0c;又称贝兹曲线或贝济埃曲线&#xff0c;是应用于二维图形应用程序的数学曲线。一般的矢量图形软件…