线程池执行以及回收原理(二)

线程回收

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)

我们在设置线程池的时候往往会设置keepAliveTime(最大存活时间),我们都知道如果超过这个存活时间,线程池会回收额外的线程达到核心线程数,

1、回收的原理是什么?

2、核心线程与非核心线程有什么区别吗?

3、非核心线程可以核心线程吗?

线程池执行以及回收原理(一)主要讲述了线程在执行过程中的创建以及如何获取task任务,下面就是getTask()的任务

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

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

        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);
        // 步骤1
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

         // 步骤2
        if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
            // 步骤2.1
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            // 步骤3
            Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

在步骤3中: workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) keepAliveTime在这里使用,表示workQueue等待keepAliveTime的时长,若果没有获取到或者超时返回null值。

workQueue具体含义什么呢?从上一篇文章可以知道线程池执行以及回收原理(一),这是一个阻塞队列,当核心线程数 =< 当前线程数 < 最大线程数时,我们将任务封装放进一个阻塞队列,这就是那个阻塞队列;

整体我们就可以知道,

1、如果队列中没有任务的,步骤3获取的r参数为空,timeout就会设置成true

2、进行步骤1的判断,假设这个线程执行的时候wc > corePoolSize成立,则timed为true,步骤2中timed && timedOutweitrue,wc >1也为true,

3、进行步骤2.1的操作,使用cas进行ctl减1的操作,返回null值,此时线程等待系统的回收。

所有的线程都进行如此的操作直到wc > corePoolSize不再成立,ctl这个工作线程的数目等于corePoolSize,此时步骤1获取的timed为false,此时步骤2的判断不再成立,执行步骤3的操作,但是注意此时timed为false,执行三元运算符中的workQueue.take(),此操作是阻塞的,直到workQueue中可以获取到值才能继续运行。这也就是整体的线程池的回收直至存活数目等于核心线程数目

有个关键参数allowCoreThreadTimeOut,这个参数默认是false,如果设置成true,所有的线程都会回收。

这样我们就可以回答上面的问题2与问题3了。

核心线程与非核心线程有什么区别?非核心线程可以核心线程吗?他们两个没有什么区别,能否成为核心线程完全是随机的,主要就是看谁先能提前进入阻塞当中,谁就会成为最终留下来的核心线程

下图是线程池的原理示意图

 

https://www.cnblogs.com/semi-sub/p/13908099.html

回复  8888可以领取面试资料,感谢各位小伙伴的关注

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

技术王老五

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

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

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

打赏作者

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

抵扣说明:

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

余额充值