当前位置: 首页 > 后端技术 > Java

Java并发——线程池的动态调整

时间:2023-04-01 16:53:34 Java

为什么需要动态调整理论公式计算出来的参数来满足不同业务系统的需求,所以动态调整线程池的参数,方便调优,找到更合适的设置.可以动态调整的看几个参数1.corePoolSize:保留在池中的线??程数,即使是空闲的,除非设置了{@codeallowCoreThreadTimeOut}(核心线程数:不管是否空闲idleaftercreation是的。线程池需要维护corePoolSize线程数,除非设置了allowCoreThreadTimeOut。)2.maximumPoolSize:池中允许的最大线程数。(最大线程数:线程池中允许创建maximumPoolSize线程。)3.keepAliveTime:当线程数大于核心时,这是多余的空闲线程在终止前等待新任务的最长时间.(生存时间:如果超过核心线程数的线程在keepAliveTime时间过后还没有收到新的任务,就会被回收。)4.unit:{@codekeepAliveTime}参数的时间单位(时间单位keepAliveTime。)5.workQueue:用于在任务执行前保存任务的队列。该队列将仅保存由{@codeexecute}方法提交的{@codeRunnable}任务。(Queueforstoringtaskstoexecute:当提交的任务数超过核心线程数时,提交的任务存放在这里,只用于存放execute方法提交的Runnable任务。所以不要在这里把它翻译成工作队列,好吗?不要给自己挖坑。)6.threadFactory:执行者创建新线程时使用的工厂。(线程工程:用来创建线程工厂,比如这里可以自定义线程名称,在分析虚拟机栈的时候,看名字就知道线程是从哪里来的,不会混淆。)7.handler:由于达到线程边界和队列容量而阻塞执行时使用的处理程序。(拒绝策略:当队列已满任务,线程数最大的线程正在工作时,此时继续提交的任务的线程池无法处理,应该实现什么样的拒绝策略。)回顾执行过程1.首先检测线程池的运行状态。如果不是RUNNING,直接拒绝。线程池必须保证任务在RUNNING状态下执行。2.如果workerCount=corePoolSize,并且线程池中的阻塞队列未满,则将任务添加到阻塞队列中。4、如果workerCount>=corePoolSize&&workerCount=maximumPoolSize,并且线程池中的阻塞队列已满,任务将按照拒绝策略进行处理,默认的处理方式是直接抛出异常。为什么可以动态调整1、JDK允许线程池用户通过ThreadPoolExecutor的实例动态设置线程池的核心策略。以setCorePoolSize为例,线程池用户在运行时调用该方法设置corePoolSize后,线程池会直接覆盖原来的corePoolSize值,并根据当前值与原始值的比较结果采用不同的处理策略。如果当前值小于当前工作线程数,则说明存在冗余工作线程。这时就会向当前空闲的工作线程发送中断请求,实现回收。多余的worker下次空闲时也会被回收;对于当前值,如果大于原来的值,并且当前队列中有任务要执行,线程池会创建一个新的工作线程来执行排队的任务。2、线程池当前状态会被处理,实现平滑修改。基于这些公共方法,我们只需要维护ThreadPoolExecutor的实例,在需要修改的时候拿到实例去修改它的参数即可。实现方案corePoolSize、maximumPoolSize、keepAliveTime直接通过消息/配置修改,队列容量可以通过LinkedBlockingQueue改写,设置容量为非final。参考https://segmentfault.com/a/11...https://mp.weixin.qq.com/s/Yb...https://www.javadoop.com/post...