核心线程,非核心线程的区别你还记得吗?

您所在的位置:网站首页 核心线程数量 核心线程,非核心线程的区别你还记得吗?

核心线程,非核心线程的区别你还记得吗?

2024-02-02 18:07| 来源: 网络整理| 查看: 265

/   今日科技快讯   /

近日,腾讯发布了2020年第三季度业绩报告。财报显示,腾讯第三季度营收1254.5亿元,市场预估1238.29亿元,去年同期972.4亿元,同比增长29%。净利润385.4亿元,同比增长89%,市场预期308.1亿元,去年同期203.82亿元。

/   作者简介   /

一晃又到了周五啦,祝大家周末愉快哦!我们下周见!

本篇文章来自小猪快跑22的投稿,通过实例带着大家一起来分析ThreadPoolExecutor源码,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章!

小猪快跑22的博客地址:

https://blog.csdn.net/zhujiangtaotaise

/   前言   /

其实大概1年前就想把线程池的源码完整的撸一遍了,但是看的时候太注重细节了,比如其中的CAS操作、AQS以及ReentrantLock的lock、tryLock等,结果就是跑偏了;所幸今年年初的时候有时间,就把AQS的源码、CAS的使用以及ReentrantLock等一些并发编程的源码撸了一遍,再来看线程池的源码,感觉还是非常的舒爽,哈哈哈。共勉。

讲线程池的原理之前,先得了解一下线程池中几个重要的概念。

核心线程数 (corePoolSize):核心线程的数量;它的作用可以这样理解:向线程池中添加任务,如果线程池中的线程数量小于 corePoolSize,那么直接新建线程执行任务;如果线程池中的线程数量大于corePoolSize,那么就会往 阻塞队列workQueue中添加任务,此时如果阻塞队列满了且线程池中的线程数量小于最大线程数 maximumPoolSize,那么也会新建一个线程执行任务;如果阻塞队列满且线程数量大于最大线程数maximumPoolSize,那么会执行饱和策略,默认的策略是抛弃要加入的任务。

最大线程数 (maximumPoolSize):如果阻塞队列满了,则判断线程池中的线程数量是否小于 maximumPoolSize,是则直接新建一个线程来处理任务,否则执行饱和策略。

阻塞队列**(workQueue)**:线程池中的线程数量大于核心线程的数量,则将新建的任务加入到阻塞队列。

空闲线程的存活时间 (keepAliveTime):线程空闲下来之后,线程的存活时间,超过这个时间还没有任务执行,则结束该线程。注意,这个回收只是回收非核心线程,比方说核心线程数是2,最大线程数是6,假设任务非常多,最后创建了6个线程来执行任务,最后后回收4个非核心线程,而核心线程不会回收,除非你任务设置要回收核心线程。

饱和策略 (RejectedExecutionHandler):当等待队列已满,线程数也达到最大线程数时,线程池会根据饱和策略来执行后续操作,默认的策略是抛弃要加入的任务。

下面来一张图来说明下:

线程池的几种状态

RUNNING: 运行状态,能够接受新的任务且会处理阻塞队列中的任务。

SHUTDOWN:关闭状态,不接受新任务,但是会处理阻塞队列中的任务,执行线程池的 shutDown()对应的就是此状态。

STOP:停止状态,不接受新的任务,也不会处理等待队列中的任务并且会中断正在执行的任务。调用线程池的 shutDownNow()对应的是此状态

TIDYING: 整理,即所有的任务都停止了,线程池中线程数量等于0,会调用 terminated()如果你自己实现线程池的话。

TERMINATED:结束状态,terminated()方法执行完了。

下面是一些重要的变量注释:

 //CAS, 它的高三位表示线程池的状态,低29位表示线程池中现有的线程数     private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));     //表示线程池线程数的bit数     private static final int COUNT_BITS = Integer.SIZE - 3;     //最大的线程数量,数量是完全够用了 0001 1111 1111 1111 1111 1111 1111 1111     private static final int CAPACITY   = (1 = STOP || workQueue.isEmpty()))成立,执行 decrementWorkerCount()将线程池的线程减1,所以此时线程池中线程的个数为1,然后 return null,即 runWorker方法中的while循环while (task != null || (task = getTask()) != null)结束。

接着会调用 processWorkerExit(w, completedAbruptly),方法如下:

private void processWorkerExit(Worker w, boolean completedAbruptly) {         if (completedAbruptly) // 正常为false,不用管             decrementWorkerCount();         final ReentrantLock mainLock = this.mainLock;         mainLock.lock();         try {             completedTaskCount += w.completedTasks;             workers.remove(w);// 从works中删除已完成的Worker         } finally {             mainLock.unlock();         }         tryTerminate(); // **注1**         int c = ctl.get();         // 线程池的状态小于STOP         if (runStateLessThan(c, STOP)) { // **注2**             if (!completedAbruptly) {                 int min = allowCoreThreadTimeOut ? 0 : corePoolSize;                 if (min == 0 && !workQueue.isEmpty())                     min = 1;                 if (workerCountOf(c) >= min)                     return; // replacement not needed             }             addWorker(null, false);         }     } 这里就不带着分析**processWorkerExit**了。下面再带着分析

5.此时核心线程Thread1执行完任务2,会再次调用 getTask方法 ,接着分析 getTask方法:

注1 :条件也是成立的,同上;执行decrementWorkerCount 使线程池的线程数减1,此时线程池中的个数等于0,然后 return null,结束 runWorker 中的 while循环。

接着就是执行 runWorker 中finally块中的processWorkerExit方法。

processWorkerExit 方法分析开始

注1:执行tryTerminate,接着分析 tryTerminate中的代码:

tryTerminate分析开始:

tryTerminate 中的 注1 条件不满足,因为线程池的状态是SHUT_DOWN,且workQueue是empty;

注2:条件if (workerCountOf(c) != 0)也不满足,此时线程个数等于0

注3:设置线程池的状态为TIDYING成功,

注4:ctl.set(ctlOf(TERMINATED, 0)) 设置线程池的状态为 TERMINATED

tryTerminate分析结束

执行 processWorkerExit 的注2,由于此时线程池的状态为TERMINATED,所以条件不成立,核心线程对应的 runWorker方法执行完了。

到此,执行 shutDown后的,所以线程(包含核心线程和非核心线程)都回收了。

本篇主要讲了 线程池中任务的执行、线程的复用、线程的回收,以及一些case被调用到的条件。

这篇文章已经太长了,包含shutDown和shutDownNow的区别,下篇再分析啦。

/   总结   /

如果不执行线程池的shutDown方法且没有调用设置核心线程空闲存活时间,那么只会回收非核心线程,不会回收核心线程,核心线程会一直阻塞

调用shutDown方法后,所有线程都会回收,这也是为什么大多数我们调用线程池的 execute方法后,会调用shutDown方法

线程池的执行流程分析

推荐阅读:

WorkManager流程分析和源码解析

我的新书,《第一行代码 第3版》已出版!

排障困难?给你的应用嵌入一个Logcat吧

欢迎关注我的公众号

学习技术或投稿

长按上图,识别图中二维码即可关注



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3