java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > ThreadPoolExecutor实现原理

java线程池ThreadPoolExecutor实现原理详解

作者:那个天真的人

这篇文章主要介绍了java线程池ThreadPoolExecutor实现原理详解,ThreadPoolExecutor是线程池实现类,会动态创建多个线程,并发执行提交的多个任务,需要的朋友可以参考下

前言

做java开发的,一般都避免不了要面对java线程池技术,像tomcat之类的容器天然就支持多线程。

即使是做偏后端技术,如处理一些消息,执行一些计算任务,也经常需要用到线程池技术。

鉴于线程池技术的重要性,接下来会分多篇介绍java中提供的ThreadPoolExecutor线程池实现的底层机制。

只有对机制了然于胸,才能更好驾驭这把利器。

线程池技术演示流程

有了以上的概念,接下来将根据 allowCoreThreadTimeOut的值分两种场景进行演示说明。

演示一: allowCoreThreadTimeOut=true

1、 初值设定: corePoolSize=2; maximumPoolSize=3;keepAliveTime=10s; workQueue容量为2; 初始状态图如下所示:

这里写图片描述

2、submit一个任务A,由于总线程数0<corePoolSize; 此时会创建一个线程执行任务A,状态图如下:

这里写图片描述

3、submit一个任务B,由于总线程数1<corePoolSize,此时会创建一个线程执行任务B,状态图如下:

这里写图片描述

4、submit一个任务C,由于总线程数 2=corePoolSize,workQueue不满,这时候任务C入队列,状态图如下:

这里写图片描述

5、submit一个任务D,很明显,任务D入队列,状态图如下:

这里写图片描述

6、submit一个任务E,这时候,线程数2=corePoolSize,workQueue也已经满了,判断发现线程数2<maximumPoolSize,所以继续创建线程执行任务E,状态图如下:

这里写图片描述

7、submit一个任务F,这时候,2=corePoolSize,workQueue已满,判断发现线程数3=maximumPoolSize,这种情况下,线程池会根据策略来决定是否要放弃当前任务,或者是把workQueue中一个任务删除,然后入队新的任务,也可以自定义策略,比如,持久化到DB之类的,或者是发出警报。我们假设是直接丢弃策略,这时候状态图不变。

8、这会没有新任务到来了,各个任务陆续执行完了,包括队列中的C和D也执行完了,这时候,由于当前场景为allowCoreThreadTimeOut=true,如果在等待keepAliveTime时间后线程仍旧无法获取新的任务,线程将会自行退出,这将导致最终所有线程都退出了,也就是又再次回到了原始状态,如下图所示:

这里写图片描述

说得更简单一些就是:在 allowCoreThreadTimeOut=true时,如果一个线程等了keepAliveTime还无法获取新任务,则退出。

演示二:allowCoreThreadTimeOut=false

1~7 的步骤与状态跟“演示一”是一样的,所以这里不再赘述,这时候状态图如下:

这里写图片描述

8、这会没有新任务到来了,各个任务陆续执行完了,包括队列中的C和D也执行完了,这时候,由于当前场景为allowCoreThreadTimeOut=false,并且线程数3>corePoolSize,这时候每个线程都感知到线程数过多,所以它们都会尝试把自己停止掉,实现中最终只会停止一个线程,剩余线程数2=corePoolSize,接下来,哪怕一直没有新任务来,这corePoolSize个线程也不会退出,一直存活着等待接收任务。这时候,状态图如下:

这里写图片描述

线程池的状态

前一部分演示了线程池的基本实现原理,这一小节介绍一下线程池的状态,线程池概括上讲有5种状态,如下图所示:

这里写图片描述

总结

理解线程池最主要是要理解线程池几个主要的配置参数,如果不看实现细节,原理还是比较简单的。在了解原理的基础上再去看代码,就会事半功倍。

到此这篇关于java线程池ThreadPoolExecutor实现原理详解的文章就介绍到这了,更多相关ThreadPoolExecutor实现原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文