java线程池
java线程池
一、线程池的7个核心参数
1. corePoolSize 核心线程数
corePoolSize 是线程池中保持活动状态的最小线程数。 即使线程是空闲的,它们也会一直保持在池中。 当有新任务提交时,线程池会优先创建核心线程来处理任务。
2. maximumPoolSize 最大线程数
maximumPoolSize 是线程池中允许的最大线程数。 如果任务数超过了核心线程数,且任务队列已满,线程池会创建新的线程,但不会超过最大线程数。
3. keepAliveTime 线程空闲时间
keepAliveTime 是非核心线程在空闲时可以存活的时间。 当线程空闲时间超过 keepAliveTime,多余的非核心线程将被终止,以减少资源消耗。这个参数配合 TimeUnit 来定义时间单位。
4. unit 时间单位
unit 是与 keepAliveTime 一起使用的时间单位。 它表示 keepAliveTime 的时间单位,可以是秒、毫秒、微秒等。
5. workQueue 任务等待队列
workQueue是一个阻塞队列,用于存储等待执行的任务。 当任务数超过核心线程数时,多余的任务会被放入任务队列中。 常见的队列类型包括 LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue 等。
6. threadFactory 线程工厂
用于创建新线程。 可以通过自定义线程工厂来配置线程的名称、优先级、是否为守护线程等属性。
7. handler 拒绝策略
handler 是当工作队列和线程池都满了之后采取的饱和策略。
jdk默认提供了四种拒绝策略:
1)AbortPolicy - 丢弃任务,并抛出拒绝执行 RejectedExecutionException 异常信息。线程池默认的拒绝策略。必须处理好抛出的异常,否则会打断当前的执行流程,影响后续的任务执行。
2)CallerRunsPolicy - 当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。一般并发比较小,性能要求不高,不允许失败。但是,由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率上必然损失较大
3)DiscardPolicy - 直接丢弃,其他啥都没有
4)DiscardOldestPolicy - 当触发拒绝策略,只要线程池没有关闭的话,丢弃阻塞队列 workQueue 中最老的一个任务,并将新任务加入
线程池中各个参数之间的关系:
说明:这些参数在创建线程池时进行配置,通过合理调整这些参数,可以使线程池适应不同的工作负载和性能需求。例如,通过调整核心线程数和最大线程数,可以优化线程池在不同负载下的性能表现。
二、 线程池处理任务的流程
如下图:
举例来说:核心线程数量为 5 个;全部线程数量为 10 个;工作队列的长度为 5。
1. 刚开始都是在创建新的线程,达到核心线程数量 5 个后,新的任务进来后不再创建新的线程,而是将任务加入工作队列;
2. 任务队列到达上线 5 个后,新的任务又会创建新的普通线程,直到达到线程池最大的线程数量 10 个;后面的任务则根据配置的拒绝策略来处理。如果没有配置,使用的是默认的配置 AbortPolicy:直接抛出异常。
3. 当前任务小于最大线程数的时候,线程资源会保持核心线程池个数的线程,其他超过的线程资源在存活时间超过之后会被回收。