详细解读ThreadPoolExecutor类的七大构造参数

ThreadPoolExecutor是Java中用于管理线程池的类,它提供了一种方便的方式来执行多线程任务。ThreadPoolExecutor的构造参数有很多,每个参数都有不同的作用和影响,下面我将详细解读每个构造参数,并尽量用通俗的语言解释它们。

首先需要明白,线程是要去执行特定任务的,这些任务通常是特定的代码段,我们需要将代码段封装成一个任务(比如Runnable),将其交给线程去执行任务。

而我们的线程池就装载了一些线程,一旦有任务来临,就可以从线程池中取出线程去执行我们的任务。ThreadPoolExecutor就可以创建出线程池,线程池的创建是需要很多“讲究”的,这些讲究就是我们本文要讲的七大构造参数,如下所示:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

corePoolSize(核心线程数):

这是线程池中始终保持存活的线程数量。
通俗地说,即使没有任务要执行,线程池也会一直保持这些核心线程的存在。

maximumPoolSize(最大线程数):

这是线程池中允许的最大线程数量。
如果当前任务数量超过核心线程数,线程池会创建新的线程,但不会超过这个最大线程数。

keepAliveTime(线程空闲时间):

当线程池中的线程数量大于核心线程数时,多余的线程在空闲时间达到这个值后会被终止并从线程池中移除。
这个时间可以理解为线程的“闲置时间”。

unit(时间单位):

指定了keepAliveTime参数的时间单位,通常是秒、毫秒等。

workQueue(任务队列):

用于存放待执行的任务的队列。
当提交的任务数量大于核心线程数时,超过核心线程数的任务会被放入这个队列中等待执行。

threadFactory(线程工厂):

用于创建新线程的工厂。
可以自定义线程的名称、优先级等属性。

handler(拒绝策略):

当任务数量超过最大线程数且队列已满时,用于决定如何处理新任务的策略。
常见的策略有抛出异常、丢弃任务、阻塞等。

举例分析

假设我们经营一家小餐馆,并且需要管理一组员工来为客人提供服务。

corePoolSize(核心员工数):

这就像是我们餐馆里一直准备好的服务员数量。不论是否有顾客,我们至少需要雇佣2名服务员。

maximumPoolSize(最大员工数):

这是我们餐馆里服务员的最大数量。最多我们可以雇佣4名服务员。

keepAliveTime(员工空闲时间):

这是指服务员在没有顾客需要服务时,可以空闲多久而不被解雇。假设是1小时。

unit(时间单位):

这是用于衡量员工空闲时间的单位,我们使用小时作为单位。

workQueue(任务队列):

这就像是一个顾客等待用餐的队列。当所有的服务员都在忙碌的时候,新的顾客会排队等待。

他们之间的关系及流程如下:

初始时,我们雇佣了2名服务员(corePoolSize),并且有一名顾客(顾客就相当于任务)在餐馆等待。
当更多的顾客进来,如果服务员不够,我们会雇佣新的服务员,但不超过4名(maximumPoolSize)。
如果有一名服务员在1小时内没有服务顾客(keepAliveTime),那么他可能会被解雇,但始终保持2名服务员。
当顾客进来时,他们会排队等待服务,就像排在任务队列中一样。
当有服务员空闲时,他们会从队列中取出下一个顾客,并为他们提供服务,然后返回继续等待。
这就是ThreadPoolExecutor参数之间的流程示例。这个线程池管理着一组服务员(线程),根据工作负载来雇佣和解雇服务员,并将顾客(任务)排队等待服务。

总的来说,任务来临会首先由core线程来执行,就像是餐馆的核心员工。当core已经有任务在身,这时候程序还有其他任务来临时,会进入workQueue队列进行排队等候被执行。程序检测到队列有没被执行的任务时,而core线程正在忙其他的任务,那么就会另开一些新线程来执行队列中的任务。

这些新线程有两个注意点,一个是这些线程在程序中存活多久?这是由keepAliveTime决定的。另一个是程序中的新线程数量最多有几个?这与maximumPoolSize是紧密相关的。

当新线程执行完一个任务时,会检测队列中还有无任务需要执行,如果没有,则进入空闲状态,从此时计时开始,到达keepAliveTime时间之前还没有执行其他任务,那么就关闭此线程。这个线程就被程序所回收了。

maximumPoolSize决定了线程池中最多有几个线程存在,而corePoolSize是自始至终永远存在的线程,所以线程池中最大能另开maximumPoolSize-corePoolSize个线程。

整体运行流程

1、线程池创建,准备好 core 数量的核心线程,准备接受任务
2、新的任务进来,用 core 准备好的空闲线程执行。
        (1) 、core 满了,就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队
列获取任务执行
        (2) 、阻塞队列满了,就直接开新线程执行,最大只能开到 max 指定的数量
        (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自
动销毁。最终保持到 core 大小
        (4) 、如果线程数开到了 max 的数量,还有新任务进来,就会使用 reject 指定的拒绝策
略进行处理
3、所有的线程创建都是由指定的 factory 创建的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值