9.线程池-2

2021-08-04  本文已影响0人  nieniemin

一、常见线程池介绍

上一节中线程池使用到了Executors.newSingleThreadExecutor()方法。接下来介绍下常用的线程池。

newSingleThreadExecutor newFixedThreadPool newCachedThreadPool

在性能上newCachedThreadPool>newFixedThreadPool>newSingleThreadExecutor。通过截图可以看到这三个方法都调用了ThreadPoolExecutor的构造方法,在执行Executors.线程池方法时,idea会提示


给我们的解释如下:

线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下:
1)FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
2)CachedThreadPool: 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

因此在使用线程池时,我们也要放弃前面使用Executors类创建线程池,采用ThreadPoolExecutor类来创建线程池。

二、ThreadPoolExecutor构造函数参数介绍

ThreadPoolExecutor构造器共有7个参数:

下图简单介绍了核心线程数、最大线程数工作,分析下核心线程数和最大线程数的关系,有助于加深理解:

(1)当提交一个任务时,先判断线程池中当前线程数量是否达到了corePoolSize,若未达到,则新建线程运行此任务,线程池创建一个新线程(worker)执行任务(task)且任务结束后将该线程保留在线程池中,不做销毁处理。除非设置了allowCoreThreadTimeOut=true时,无论线程数多少,那么线程处于空闲状态超过一定时间(keepAliveTime)就会被销毁掉。

(2)如果达到了corePoolSize,判断工作队列(workQueue)是否已满,未满则将新的任务提交到工作队列中

(3)如果workQueue满了,判断线程池中的线程数量是否达到了maximumPoolSize,如果未达到,则新建一个工作线程来执行这个任务,如果达到了则使用饱和策略来处理这个任务。注意: 在线程池中的线程数量超过corePoolSize时,对于右侧的非核心线程数每当有线程的空闲时间超过了keepAliveTime,这个线程就会被终止。直到线程池中线程的数量不大于corePoolSize为止。

线程池工作

workQueue
用来保存等待被执行的任务的阻塞队列,且任务必须实现Runnable接口,阻塞队列如下:

饱和策略
当工作队列满且线程个数达到maximunPoolSize后所采取的策略

参考:
https://zhuanlan.zhihu.com/p/87733949
https://blog.csdn.net/qq_33323054/article/details/106923732

上一篇下一篇

猜你喜欢

热点阅读