线程池基本了解及其参数配置

前言

在面试的过程中,总会说:谈谈你对线程池的理解。

 什么是线程池?

线程池有什么优势?

如何创建线程池?

线程池的参数配置是什么?

常用线程分类有什么?

为此,做一个总结。巩固我那薄弱的知识。

 什么是线程池? 

        存放线程的一个空间?区域?池子。可以说线程池的内部维护了若干的线程。这些线程等待着任务来进行执行。就如同一个共享单车基地一样。维护了很多的单车,等你有人来使用。对于线程池,如果有任务就分配一个线程池中的线程来执行,如果线程池中的线程用完了就把这些任务反放在工作队列中,放对列满执行了再,或者没有(不是真的没有只是为空)队列来方,直接创建一个新线程来执行。

同样是创建线程,线程池创建有什么优势呢?

线程池的优势?       

        1.降低资源的消耗:他可以重复利用已经创建过的线程来执行任务,减少多次创建和销毁的消耗

        2.提高相应的速度,这里的速度不是线程创建的速度,而是从原来的先创建线程,然后再执行任务,变成了统一创建好了线程,下次任务来了之后直接执行。省去了每次创建的时间消耗

        3.提高线程的可管理性:使用线程池,可以统一的分配、调优、和监控。

那么我们应该如何创建线程池呢?

如何创建线程池

我们通过ThreadPooExecutor的构造方法来创建线程池

这里就需要理解这七个参数分别是什么

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, 0, 0, null, null, null, null);

线程池的参数配置

1,核心线程数量

2,线程池最大线程数量

3,线程池的非核心线程的存活时间

4,时间单位

5,工作队列。

6,创建线程的线程工厂

7,拒绝策略

1.线程池核心线程数量:

可以理解成线程池最小的线程数量,核心线程数量不会被回收,而且核心线程在创建任务的时候立刻被创建并且执行任务。

2.线程允许创建的最大线程数量(这个最大线程数量是包含了核心线程数量的)当任务大于核心线程数量,且工作队列已满,那么会创建非核心线程来执行任务。

3.线程池的非核心线程存活时间(见名知意)

4.是上面那个存活时间的时间单位

5.工作队列,BolckingQueue,一个阻塞工作队列,用来存储等待执行的任务。

阻塞队列的实现机制是生产者消费者模型,一个线程负责存储任务,一个线程负责取出任务。

常用的BlokingQueue

ArrayBlockingQueue:这是一个有界队列,基于数组实现,维护了一个定长数组,按照先进先出排序。

LinkedBolckingQueue:这是一个无界队列,容量可以设置,如果不设置的话是Interger.MAX_VALUE。这个的吞吐量一般比ArrayBlockingQueue高。

(FixedThreadPool、SingleThreadExecutor线程使用LinkedBolkingQueue队列。)

LiknkedBolckingQueue是一个无界队列,在这种队列情况下,最大线程数是一个无效参数,但是在设计的时候依然设计了最大线程数的配置。

DelayedWorkQueue是一个基于堆结构的延迟队列。底层基于数组实现。初始容量是16,他的排序是按照指定的延迟时间从小到大排序的。

ScheduledThreadPool使用了这个队列

PriorityBlokingQueue(优先任务队列)

按照用户的需求来设置优先等级,调整任务的执行顺序。

SynchronousQueue(同步队列)

他不存储元素的阻塞队列(内部没有保存元素的数据结构)。使用SynchronousQueue队列,提交的任务不会被保存,总是立刻被执行。

6:创建线程的线程工厂:

一般使用默认的线程工厂,如果有一些自己的设计,比如改变线程的名称,那么可以自定义一个线程工厂。

7:拒绝策略

默认策略是丢弃任务并且抛出异常

还有丢弃任务

还有丢弃队列中的末尾任务(最旧的任务,也就是最早进入队列的任务)

由有调用线程处理该任务

线程池的运行过程:

提交任务:核心线程池是否已满:如果没有满就执行创建核心线程并且执行任务。如果核心线程池满了,就放入队列中,如果队列满了,就去判断线程池中的线程是否已经超过最大线程数。如果是就按照拒绝策略处理。没有满就创建非核心线程来执行任务。

4.常见线程池有哪些以及使用场景?

FixedThreadPool

线程数固定的线程池:

核心线程数和最大线程数一致

非核心线程的空闲存活时间即KeepALiveTime为0

阻塞队列为无界队列LinkedBlockingQueue

工作机制:

a.提交线程任务

b.如果线程数少于核心数创建核心线程执行任务,如果等于核心线程,把任务添加到LinkedBlckinghQueue阻塞队列,如果线程执行完,就去阻塞对了取任务,继续执行。

适用于处理CPU密集型任务,确保CPU在长期被工作线程使用的情况下,尽可能少的的分配xianc

CachedThreadPool(可缓存线程池)

线程数根据任务动态调整的线程池

核心线程数0,最大线程数是Interger.MAX_VALUE,工作队列是synChronousQueue同步队列。非核心线程空闲存活时间为60秒

工作机制

提价线程任务,因为核心数为-0,所以任务之间加入到SynchronousQueue工作队列中,判断是否有空闲线程,如果有就取出去执行,如果没有就新建一个。

SingleThreadExecutor 单线程化的线程池

线程池参数: 核心线程数1,最大线程数1,阻塞线程是LInkedBlockQueue,f非核心线程数存活为0秒

适用于 串行执行任务的场景,将任务按顺序执行。

ScheduledTheadPool

能实现定时、周期性任务的线程池

线程池参数:

最大为Integer。MAX_VALUE

阻塞队列是DelayedWorkQueue

keepAliveTime为0

执行周期性任务,并且需要限制线程数量的需求场景。

线程 池的状态

线程池的状态:Running、shutdown、stop、tidying、terminated

rounning:运行状态,线程池一旦被创建就,处于running状态。并且线程池中的任务为0;

shutdown,关闭状态,不会接受新任务,但会处理工作队列中的任务。(使用shutdown()方法进入shutdown状态)

stop:停止状态,该状态的线程不会接收新任务,也不会处理阻塞队列的中如,而且会中断正在运行的任务。

terminated:terminated表示线程池彻底终止

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
配置Spring Boot线程池时,合理配置核心参数是非常重要的。以下是一些建议: 1. 核心线程数(corePoolSize):核心线程数是线程池中同时执行任务的最小线程数。根据应用程序的负载和资源限制,可以根据需求进行调整。通常,它应该设置为能够处理正常负载的数量,以避免过多的线程创建和销毁开销。如果你的应用程序是CPU密集型任务,可以设置为CPU核心数的两倍左右。 2. 最大线程数(maxPoolSize):最大线程数是线程池中允许存在的最大线程数。如果任务量超过了核心线程数,线程池会创建新的线程来执行任务,直到达到最大线程数。根据系统负载和资源限制,可以根据需求进行调整。一般情况下,最大线程数应该根据系统资源限制来设置,以避免过多的线程造成系统资源耗尽。 3. 队列容量(queueCapacity):队列容量是用于存放等待执行任务的队列大小。当所有核心线程都在执行任务并且队列已满时,新任务会被拒绝执行。根据应用程序的需求和系统资源限制,可以根据需求进行调整。如果任务的到达速率很高,可以考虑使用无界队列(如`LinkedBlockingQueue`),以避免任务被拒绝执行。 4. 线程存活时间(keepAliveTime):线程存活时间是非核心线程的空闲时间,超过该时间将被终止。这个参数主要适用于非核心线程,因为核心线程始终保持活动状态。根据应用程序的负载和响应时间要求,可以根据需求进行调整。 请注意,以上参数的合理配置取决于你的应用程序需求、系统资源和预期的性能表现。通过监控和测试,可以进行适当的调整和优化。 希望这些信息对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值