线程池的状态及KeepAliveTime参数

Java中的线程池的线程数量如何确定? 线程池是一种“池化”的线程使用模式,通过创建一定数量的线程,让这些线程处于就绪状态来提高系统响应速度,在线程使用完成后归还到线程池来达到重复利用的目标,从而降低系统资源的消耗。 阅读详情



原文:https://segmentfault.com/a/1190000004998918



五个状态

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

循环getTask方法

/**
     * Performs blocking or timed wait for a task, depending on
     * current configuration settings, or returns null if this worker
     * must exit because of any of:
     * 1. There are more than maximumPoolSize workers (due to
     *    a call to setMaximumPoolSize).
     * 2. The pool is stopped.
     * 3. The pool is shutdown and the queue is empty.
     * 4. This worker timed out waiting for a task, and timed-out
     *    workers are subject to termination (that is,
     *    {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
     *    both before and after the timed wait.
     *
     * @return task, or null if the worker must exit, in which case
     *         workerCount is decremented
     */
    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);
            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }
            boolean timed;      // Are workers subject to culling?
            for (;;) {
                int wc = workerCountOf(c);
                timed = allowCoreThreadTimeOut || wc > corePoolSize;
                //默认allowCoreThreadTimeOut为false,除非程序指定
                //(1)当没有超过核心线程时,默认allowCoreThreadTimeOut为false时
                //timed值为false,始终break掉,不会销毁线程
                //(2)当超过核心线程数,默认allowCoreThreadTimeOut为false时
                //timed值为true,如果超过最大值,则销毁;如果timeout过,则销毁
                // 如果allowCoreThreadTimeOut为true,则timed始终为true
                if (wc <= maximumPoolSize && ! (timedOut && timed))
                    break;
                if (compareAndDecrementWorkerCount(c))
                    return null;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

线程池状态大于SHUTDOWN值的两种情况

1、调用shutdown方法

当线程池调用了shutdown方法,线程池的状态会首先被设置为SHUTDOWN,然后遍历线程池中所有线程,调用一次interrupt方法,如果在休眠中的线程将会激活,激活后的线程以及调用shutdown方法本身的线程都会尝试去调用tryTerminate方法,该方法将判定如果线程池中所有记录的线程数为0,则将线程状态改为TERMINATED,这个值为3,将大于SHUTDOWN状态值。

2、调用shutdownNow方法

当线程调用了shutdownNow方法后,首先将线程的状态修改为STOP,这个状态是大于SHUTDOWN值的,接下来它也会通过中断激活线程,只是它来的更暴力一些,连加锁和一些基本判断都没有,直接中断;在调用tryTerminate之前会先清空阻塞队列中所有的元素,这些元素被组装为一个List列表作为shutdownNow方法的返回值。换句话说,没有执行的任务在shutdownNow执行后的返回值中可以得到。在程序某些必要的情况下,可以通过线程池的isTerminating,isTerminated,isStopped,isShutdown来对线程做一些状态判定。

KeepAliveTime参数

workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)

当阻塞队列中没有任务时,等待时间达到keepAliveTime毫秒值时就会被自动唤醒,而不会永远地沉睡下去。

keepAliveTime,如果是通过newCachedThreadPool的话,默认是1分钟超时,如果遇到前面所提到的瞬间冲击,那么线程池数量将瞬间快速膨胀,而且这些瞬间膨胀的线程的生命周期最少在1分钟以上。

如果设置了该参数,那么当timeout的时候,就return null,就会跳出循环,回收线程。

if (wc <= maximumPoolSize && ! (timedOut && timed))
                    break;
                if (compareAndDecrementWorkerCount(c))
                    return null;

allowCoreThreadTimeout : 默认情况下核心线程不会退出,可通过将该参数设置为true,让核心线程也退出。

默认的Executors工厂,只有newCachedThreadPool,timeout为60秒,出现timeout情况下,而且线程数超过了核心线程数,会销毁销毁线程。保持在corePoolSize数(如果是cached的,corePoolSize为0)。

   /**
     * Timeout in nanoseconds for idle threads waiting for work.
     * Threads use this timeout when there are more than corePoolSize
     * present or if allowCoreThreadTimeOut. Otherwise they wait
     * forever for new work.
     */
    private volatile long keepAliveTime;
    /**
     * If false (default), core threads stay alive even when idle.
     * If true, core threads use keepAliveTime to time out waiting
     * for work.
     */
    private volatile boolean allowCoreThreadTimeOut;

线程池最小是corePoolSize,最大是maximumPoolSize,除非设置了allowCoreThreadTimeOut和超时时间,这种情况线程数可能减少到0,最大可能是Integer.MAX_VALUE。

Core pool size is the minimum number of workers to keep alive(and not allow to time out etc) unless allowCoreThreadTimeOut is set, in which case the minimum is zero.

/**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to <tt>execute</tt> will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    /**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available, and uses the provided
     * ThreadFactory to create new threads when needed.
     * @param threadFactory the factory to use when creating new threads
     * @return the newly created thread pool
     * @throws NullPointerException if threadFactory is null
     */
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }

超时timeout设置为0的话,表示不等待

public E poll(long timeout, TimeUnit unit) throws InterruptedException {
        return pollFirst(timeout, unit);
    }

具体如下

public E pollFirst(long timeout, TimeUnit unit)
        throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            E x;
            while ( (x = unlinkFirst()) == null) {
                if (nanos <= 0)
                    return null;
                nanos = notEmpty.awaitNanos(nanos);
            }
            return x;
        } finally {
            lock.unlock();
        }
    }


Java线程池的总结 今天跟大家分享Java线程池的知识。 1 为什么需要线程池 在当今计算机的CPU计算速度非常快的情况下,为了能够充分利用CPU性能提高程序运行效率我们在程序中使用了线程。但是在高并发情况下会频繁的创建和销毁线程,这样就变相的阻碍了程序的执行速度,所以为了管理线程资源和减少线程创建以及销毁的性能消耗就引入了线程池。 2 什么场景下适合使用线程池 当服务器接收到大量任务时,如果使用线程池可以大量减少线... 阅读详情

相关推荐

Dify插件离线部署全攻略:从下载到安装的完整流程

本文详细介绍了Dify插件离线部署的完整流程,针对企业内网等无网络环境需求。核心步骤包括在联网环境下载插件包、在特定Python 3.12.9环境下使用专用工具进行离线重打包,以及最终在离线Dify环境中安装验证。重点解决了离线安装的核心难题,并提供了环境配置、批量处理和故障排查等实用技巧,帮助用户实现Dify插件的顺利离线部署。

seed的博客 656

线程池参数及合理设置

点击上方关注 “终端研发部”设为“星标”,和你一起掌握更多数据库知识一、线程池的7大核心参数1.corePoolSize核心线程数目核心线程会一直存活,及时没有任务需要执行,当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理当设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭2...

这个时代,作为程序员可能要学习小程序 9526

海康视觉平台VisionMaster实战入门:从通讯配置到工具应用

本文为海康VisionMaster视觉平台实战入门指南,详细介绍了从软件安装准备、与PLC等外部设备的通讯配置,到匹配定位、测量、畸变矫正等核心工具的应用方法。通过实战案例拆解,帮助工程师快速掌握如何搭建完整的机器视觉检测与引导定位系统,实现工业自动化项目落地。

weixin_29224309的博客 1006

Java多线程之线程池的参数和配置

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

MRZHQ的博客 4836

Amesim与Simulink联合仿真:S-Function接口配置与实战避坑指南

本文详细介绍了Amesim与Simulink联合仿真中S-Function接口的配置方法与实战避坑指南。从环境搭建、编译器配置到S-Function接口实战,逐步解析关键步骤与常见问题解决方案,帮助工程师高效实现多领域系统仿真,特别适合汽车、航空航天等复杂系统建模场景。

weixin_29173777的博客 343

【R-terra包|第一节】- 栅格相关性、散点图 、波段的计算与异常值处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 —```mermaid flowchat st=>start: 开始 e=>end: 结束 op=>operation: 我的操作 cond=>condition: 确认? st->op->cond cond(yes)->e cond(no)->op 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能.

地理空间科学的博客 5614

Java 线程池设置多大合适

线程池学习纪要

轩1024的博客 2337

商用车重型多挡位机械式变速器(AMT)结构设计与仿真分析

本文针对商用车重型AMT变速器开展结构设计与仿真分析。设计采用12挡双中间轴结构,匹配400kW柴油发动机,最大扭矩2000Nm。通过等比级数分配传动比(头挡14.5,最高挡0.78),采用主副箱组合实现多挡位。双中间轴结构可抵消径向力,提升承载能力。关键设计包括:235mm中心距、4.5-5.0mm齿轮模数、锁环式同步器和复合润滑系统。通过Python参数化建模进行强度校核,计算显示中间轴在2000Nm工况下等效应力满足安全系数要求(屈服强度850MPa,安全系数≥2)。该设计解决了传统MT变速器操作强度

AI的内部世界的博客 113

深入理解 Java 线程池:线程池参数调优与技巧

线程池是一种管理和重用线程资源的机制。通常情况下,每个任务都需要一个独立的线程来执行。当任务变得越来越多,每个任务都创建一个新线程就会导致系统负荷过重。这时候线程池的使用就能很好地解决这个问题。线程池维护了一组空闲线程,当有任务需要执行时,就从线程池中选择一个空闲的线程执行任务,当任务执行完成后,这个线程就会被重新放回线程池,供下一次任务使用,这样可以节省线程创建和销毁的时间成本,提高系统的执行效率和响应速度。Java 中的线程池实现在Executor。

csdn1234561231的博客 1881

【YOLOv11改进[Backbone]】 使用Ghostnetv2替换Backbone

使用Ghostnetv2替换Backbone

静谧、淡雅 518

【用unity实现100个游戏之7】实现一个类《杀戮尖塔》的卡牌回合制游戏(附项目源码)

【用unity实现100个游戏之7】实现一个类《杀戮尖塔》的卡牌回合制游戏(附项目源码)

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1万+

线程池(ThreadPoolExecutor)重要参数解析

ThreadPoolExecutor线程池继承ExecutorService,用来解决2个问题: 执行大量异步任务的时候,通过每个线程一个任务的方法,减少线程调用开销,提升性能; 设置线程池最大线程数,管理线程资源的调用。执行大量任务的时候会不断消耗线程; 常见的三种线程池: newCachedThreadPool 优点:任何需要的时候都会创建新线程执行任务,当有可用的空闲线程(空闲线程在...

茹煜得氺的博客 620

【1.2】Costas环的基本原理概述

Costas环是一种用于载波恢复的相干解调技术,可直接从BPSK等抑制载波信号中恢复本地载波并完成解调。其核心结构包含同相/正交双支路处理,通过混频、低通滤波后,利用I/Q支路信号乘积进行相位误差检测,经环路滤波器调节VCO输出频率,实现载波同步。课程将重点讲解Costas环的MATLAB仿真实现、系统性能分析及FPGA开发,包括信号产生、频偏模拟、滤波器设计等模块,并通过AWGN信道和不同频偏条件下的测试验证系统性能。该技术无需单独提取载波,在数字通信系统中具有重要应用价值。

fpga/matlab/simulink算法仿真工程 450

java线程池

1.corePoolSize:在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中 2.maximumPoolSize:当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程数量达到maxPoolSize 3.keepAliveTime:表示线程没有任务执行时最...

neusoft-mengxiaoming的专栏 221

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【多线程】线程池

3.keepAliveTime:多余的空闲线程的存活时间,当前线程池数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止。7.handler:拒绝策略,表示当队列满了并且工作线程-大于等于线程池的数量最大线程数(maxinumPoolSize)时如何来拒绝请求执行的runnable的策略。6.threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可。

王佑辉的博客 6829

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

线程池详解

一. 线程池的好处 降低资源消耗。通过重复利用已创建的线程,降低线程创建和销毁造成的消耗。 提高响应速度。当任务到达时,任务可以不需要等待线程的创建就能直接执行。 增加线程的可管理性。线程是稀缺资源,使用线程池进行同一个的分配,调优和监控。 二. 线程池的七个参数 corePoolSize(线程池的基本大小):线程池维护的一个最小线程数量。一旦创建出来,只要不大于corePoolSize数量,就算线程处于空闲也不会被销毁。这个参数就是线程池的最小线程数量。 maximumPoolSize(线程

m0_46566541的博客 729

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【学习笔记】Java——线程池

线程池学习笔记

qq_45192089的博客 414

Java线程池解析

LinkedBlockingQueue(可设置容量队列)基于链表结构的阻塞队列,按FIFO排序任务,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE,吞吐量通常要高于ArrayBlockingQuene;在使用线程池处理任务的时候,任务代码可能抛出RuntimeException,抛出异常后,线程池可能捕获它,也可能创建一个新的线程来代替异常的线程,我们可能无法感知任务出现了异常,因此我们需要考虑线程池异常情况。...

m0_73330311的博客 785

深入了解线程池

深入了解线程池 1、线程池 线程池介绍 线程池,顾名思义就是一个线程缓存,线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,因此Java中提供线程池对线程进行统一分配、调优和监控 作用:线程池做的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。 优点: 线程复用。减少线程创建,消亡的开销,提高性能; 提高响应速度。当任务到达时,任务可以不需要

一名蒟蒻的博客 1270

JDK8 ThreadPoolExecutor 线程池源码深度解析(附几种线程池的扩展方式)

实现 RejectedExecutionHandler 重写 rejectedExecution 方法。//自定义处理方式,可以先打个日志 xxx 被我拒绝了 然后我把它放到了 redis 里 ... //log("r rejected") //save r in kafka、mysql、redis } }// 自定义的线程池类,继承自ThreadPoolExecutor private EagerThreadPoolExecutor executor;

秀强的专栏 710

Java 线程池(一)

线程池简介 使用线程池可以很好的提高性能,线程池在运行之初就会创建一定数量的空闲线程,我们将一个任务提交给线程池,线程池就会使用一个空闲的线程来执行这个任务,该任务执行完后,该线程不会死亡,而是再次变成空闲状态返回线程池,等待下一个任务的到来。在使用线程池时,我们把要执行的任务提交给整个线程池,而不是提交给某个线程,线程池拿到提交的任务后,会在内部寻找是否还有空闲的线程,如果有,就将这个任务提交给...

Meldoy_mgh的博客 493

Java 线程池 — ThreadPoolExecutor

线程池:基于池化思想管理线程的工具,维护多个线程等待分配任务,避免线程创建 / 销毁的开销,控制线程数量防止资源耗尽。

2403_85207115的博客 797

Java线程池ThreadPoolExecutor详解(一篇就够了)

Executor框架主要由三部分组成,任务,任务的执行者,执行结果,ThreadPoolExecutor和ScheduledThreadPoolExecutor的设计思想也是将这三个关键要素进行了解耦,将任务的提交和执行分离。任务在和中任务是指实现了Runnable接口和Callable接口的类,中将任务转换成FutureTask类,中任务被转换成类,该类继承FutureTask,并重写了run方法,实现了延时执行任务和周期性执行任务。任务的执行者包括任务执行机制的核心接口Executor的接口的和。...

m0_67393039的博客 1985

JAVA线程池源码详解

线程池存在的意义 线程是CPU的稀缺资源,而JAVA的创建与销毁都会导致操作系统的状态切换,这个过程会极大的消耗CPU资源,如果无限制的创建线程,还会降低系统的稳定性。为了避免过多的消耗资源,就需要设法重用线程,于是线程池的概念应运而生。 线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理...

ghh_all4you的专栏 196
上一篇: Java中的经典算法之冒泡排序(Bubble Sort) 及优化
下一篇: 深入理解JVM--JVM垃圾回收机制
还不够
博客等级 码龄16年 113粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值