Java线程池系列--keepAliveTime的作用(原理)

本文深入探讨Java线程池中keepAliveTime参数的作用原理。解释了该参数如何帮助控制非核心线程的生存周期,并通过源码分析展示了线程池内部是如何判断线程的活跃状态及决定其存亡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文网址:Java线程池系列--keepAliveTime的作用(原理)_IT利刃出鞘的博客-CSDN博客

简介

本文介绍Java的线程池中的keepAliveTime的作用

概述

worker 线程会从阻塞队列中获取需要执行的任务,这个方法不是简单的 take 数据。

你也许好奇是怎样判断线程有多久没有活动了,是不是以为线程池会启动一个监控线程,专门监控哪个线程正在偷懒?想太多,其实只是在线程从工作队列 poll 任务时,加上了超时限制,如果线程在 keepAliveTime 的时间内 poll 不到任务,那我就认为这条线程没事做,可以干掉了 。

源码分析

ThreadPoolExecutor#getTask() 

 private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {//自旋
            int c = ctl.get();
            int rs = runStateOf(c);
            /** 对线程池状态的判断,两种情况会 workerCount-1,并且返回 null
 			 1. 线程池状态为 shutdown,且 workQueue 为空(反映了 shutdown 状态的线程池还是
			要执行 workQueue 中剩余的任务的)
			 2. 线程池状态为 stop(shutdownNow()会导致变成 STOP)(此时不用考虑 workQueue
			的情况)
			**/

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;;//返回 null,则当前 worker 线程会退出
            }

            int wc = workerCountOf(c);

			// timed 变量用于判断是否需要进行超时控制。
			// allowCoreThreadTimeOut 默认是 false,也就是核心线程不允许进行超时;
 			// wc > corePoolSize,表示当前线程池中的线程数量大于核心线程数量;
 			// 对于超过核心线程数量的这些线程,需要进行超时控制
            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

			/**
			  1. 线程数量超过 maximumPoolSize 可能是线程池在运行时被调用了 setMaximumPoolSize()
			  被改变了大小,否则已经 addWorker()成功不会超过 maximumPoolSize
			  2. timed && timedOut 如果为 true,表示当前操作需要进行超时控制,并且上次从阻塞队列中
			  获取任务发生了超时.其实就是体现了空闲线程的存活时间
			**/
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
            /**
			根据 timed 来判断,如果为 true,则通过阻塞队列 poll 方法进行超时控制,如果在
			keepaliveTime 时间内没有获取到任务,则返回 null.
			否则通过 take 方法阻塞式获取队列中的任务
			**/
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null) //如果拿到的任务不为空,则直接返回给 worker 进行处理
                    return r;
                timedOut = true;// 如果 r==null,说明已经超时了,队列中仍然没有任务,此时设置timedOut=true,在下次自旋的时候进行回收
                
            } catch (InterruptedException retry) {
            // 如果获取任务时当前线程发生了中断,则设置 timedOut 为false 并返回循环重试
                timedOut = false;
            }
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT利刃出鞘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值