ThreadPoolExecutor 源码剖析之 - keepAliveTime 的实现原理

本文深入剖析了ThreadPoolExecutor中keepAliveTime的工作原理,通过分析execute方法、addWorker方法及其内部的Worker工作模式,揭示了当线程池中线程大于corePoolSize且超过keepAliveTime无新任务时,如何实现线程的超时释放。重点讲解了runWorker方法和getTask方法在这一过程中的作用。
摘要由CSDN通过智能技术生成

背景

Java 中的 ThreadPoolExecutor 是 JUC 包中十分重要的成员,主要提供了一个线程池管理的工作。关于它的用法,很多博客都有提及,包括 corePoolSize, 阻塞队列 blockQueue, 最大池大小 maxPoolSize, 拒绝策略 RejectedExecutionHandler ,和存活时间 keepAliveTime, 都已经有很多文章。我们都知道 keepAliveTime 指的是当当前线程池中线程大于 corePoolSize 的时候,如果超过 keepAliveTime 还没有新的任务,则释放大于 corePoolSize 部分的线程。但是它是怎么实现的,本文我就来给大家剖析一下。

头脑风暴

在开始看源码之前,我们先思考一下,如果要做到超时释放,应该怎么做。一种简单的方式就是启动一个线程,这个线程不断的轮询线程池当前线程的状态,发现有空闲的线程则调用中断方法尝试中断线程。

从提交开始看起

execute 方法

if (command == null)
    throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
    if (addWorker(command, true))
        return;
    c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
    int recheck = ctl.get();
    if (! isRunning(recheck) && remove(command))
        reject(command);
    else if (workerCountOf(recheck) == 0)
        addWorker(null, false);
}
else if (!addWorker(command, false))
    reject(command);

execute 方法很好理解,就是判断当前线程池中活跃线程是否小于 corePoolSize, 如果超过,则进入阻塞队列,还不行就创建新 worker,如果创建失败了,那么就进入拒绝策略。我们可以看到关键的执行方法是 addWorker 方法,然后我们看看 addWorker 做了什么

addWorker 方法

addWorker 分为两个部分,我们先来看第一个部分

addWorker 第一部分

retry:
for (;;) {
    int c = ctl.get();
    int rs = runStateOf(c);

    // Check if queue empty only if necessary.
    if (rs >= SHUTDOWN &&
        ! (rs == SHUTDOWN &&
           firstTask == null &&
           ! workQueue.isEmpty()))
        
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值