阿里巴巴手册中有一个建议:
[强制]不允许线程池使用执行者创建。取而代之的是,通过ThreadPoolExecutor,这种处理方法使写作学生更清楚地阐明了线程池的操作规则,并避免了资源耗尽的风险。
如果您经常根据执行者提供的工厂方法创建线程池,则很容易忽略线程池的实现。特别是对于拒绝策略,因为使用执行者在创建线程池时不会传递此参数默认值通常会忽略。
让我们看一下与线程池有关的实现原则,API和实例。
实用应用中的线程池的创建主要是:
ThreadPoolExecutor可以实现线程池的创建。ThreadPoolExecutor相关类图如下:
从类图可以看出,ThreadPoolExecutor最终实现了执行程序接口,这是线程池的实际实现。
在热点虚拟机中,Java中的线程将被映射为操作系统的线程。在Java虚拟机级别,用户将多个任务提交给执行程序框架。执行人负责分配线程执行它们;在操作系统级别,操作系统将把这些线程分配给处理器执行。
任务ThreadPoolExecutor接受两种类型的任务:Callace和Runnable。
任务执行器执行程序框架的核心接口是执行程序,它指示了任务的执行器。
可以从上面的类图中可以看出,执行程序的子接口是executorService。底部有两个主要的实现类:threadpoolexecutor和scheduledthreadpoolexecutor(从threadpoolexecutor集成)。
执行结果未来接口表示异步执行结果,其实现类是FutureTask。
这三个字符之间的处理逻辑图如下:
提交(提交)的线程执行以下过程:
当线程池执行执行方法时,主要存在以下四个情况:
线程池采用上述过程,用于设计获得全局锁定的次数。线程池完成预热后(当前正在运行的线程数大于或等于CorePoolsize),几乎所有concute方法调用都会执行第二步。
顺便说一下,回顾线程状态的状态转换,在JDK中的线程类中提供枚举类,该类别的线程状态的示例:
总共定义了6个枚举值,实际上代表了5种线程状态:
计划关系转换图:
当new thread()指示此线程处于新(新状态)时;呼叫thread.start()方法指示此线程在运行中(运行状态);
但是可运行的状态包含两个状态:Ready(Ready State)和运行。按下start()方法,线程不一定会获得CPU时间胶片。目前,它已经准备就绪。等待CPU时间平板电脑。当获得CPU时间胶片时,它处于运行状态。
在操作过程中调用同步的同步代码块,但不要获取锁定。目前,它将在块中(阻止状态)。重新锁定锁定时,它将变为运行状态。在代码执行过程中,可能会在Object.Wait()中遇到一些等待方法。它将终止。
线程池中的状态指示线池的五个状态通过2个二进制位置(位):
ThreadPoolExecutor创建一个线程池API:
参数说明:
当创建的线程数等于CorePoolSize时,将添加任务中的任务,以维护可运行的对象等待执行。
阻塞队列通常具有以下类型:
当无法处理任务时,线程池开始执行拒绝策略。
支持拒绝策略:
执行者是一个帮助课程,提供了一种创建多个预集线程池的方法:newsinglethreadexecutor,newfixedthreadpool,newcachedhreadpool等。
如果您查看源代码,您会发现执行者本质上是实现了几种默认的ThreadPoolExecutor。不建议使用Alibaba开发手册来使用执行者默认值,从而允许用户直接通过ThreadPoolExecutor创建。
opecutors.newsinglethreadexecutor()创建一个单线线程池。此线程池只有一个线程工作,也就是说,它等于在单个线程中执行所有任务。如果由于异常而结束的线程,将会有一个替换它的新线程。此线程池确保所有任务的执行顺序均在任务中的提交顺序实现。
这种类型的线程池的结构图:
此线程池的功能:
opecutors.newfixedthreadpool()创建一个固定的 - 尺寸线程池。每个时间提交任务,创建一个线程,直到线程达到线程池的最大尺寸。线程池的大小达到最大值,它将保留,它将保留不变。如果由于执行异常而导致线程结束,则线程池将补充新线程。
这种类型的线程池的结构图:
此线程池的功能:
opecutors.newcathedthreadpool()创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需的线程,则将恢复一些免费(60秒(60秒)的任务)线程。当任务数量增加时,此线程池可以明智地添加新线程以处理任务。该线程池不会限制线程池的大小,并且线程池的大小取决于操作系统的最大线程大小(或JVM)可以创建。
这种类型的线程池的结构图:
此线程池的功能:
opecutors.newscheduledthreadpool()创建一个长线程池,以支持时间和周期性任务执行。
此线程池图:
此线程池的功能:
介绍了opecutors.newworkStealingPool()JDK8来创建给定的并行性,该平行性用足够的线程池支持给定的并行性,并使用多个队列减少竞争。
执行人方法的缺点1)newFixedThreadPool和newsInchreadExecutor:允许的请求队列长度是Integer.max_value,它可能会积累大量请求,从而导致OOM。max_value,可能会创建大量线程,从而导致OOM。
要合理地配置线程池,您需要首先分析任务的特征,并且可以从以下角度进行分析:
此外,您还需要查看系统内核的数量:
根据任务所需的CPU和IO资源,可以将其分为:
任务实施类:
自定义threadlocalexcutor:
看似简单的线程池创建,其中包含各种知识,集成和连接,并根据特定方案与特定参数建立,以实现最佳效果。
总而言之,这是:
博客作者简介:“ Springboot Technology Inner Book”技术书籍作者,喜欢学习技术,撰写技术干货文章。
公共帐户:博客作者的公共帐户“计划的新愿景”,欢迎关注?
技术交流:请联系博客微信:Zhuan2quan
参考文章:
[1] https://www.jianshu.com/p/94852bd1a283
[2] https://blog.csdn.net/jek123456/article/details/90601351
[3] https://blog.csdn.net/z_s_s_z2016/article/details/81674893
[4] https://zhuanlan.zhihu.com/p/33264000
[5] https://www.cnblogs.com/semi-sub/p/13021786.html