ThreadPoolExecutor构造参数以及执行流程

简介: ThreadPoolExecutor构造参数以及执行流程

ThreadPoolExecutor 构造参数

ThreadPoolExecutor 是 Java 中 java.util.concurrent 包提供的一个强大的线程池实现。它提供了多种构造方法,但最常用的构造函数如下:

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

下面是每个参数的详细说明:

  • 「corePoolSize」: 核心线程数 —— 线程池中始终保持的线程数,即使它们处于空闲状态。除非设置了 allowCoreThreadTimeOut,否则它们不会因为闲置超时而被回收。
  • 「maximumPoolSize」: 最大线程数 —— 线程池中允许的最大线程数。当工作队列满了之后,线程池会创建新线程,直到达到这个最大值。
  • 「keepAliveTime」: 空闲线程的存活时间 —— 当线程数超过核心线程数时,这是超过核心线程数的线程在空闲时要等待新任务的最长时间。
  • 「unit」: keepAliveTime 的时间单位 —— TimeUnit 是一个枚举,提供了时间单位,如 TimeUnit.SECONDS
  • 「workQueue」: 工作队列 —— 用于在执行任务之前保存任务的队列。这个队列将仅保存由 execute 方法提交的 Runnable 任务。
  • 「threadFactory」: 线程工厂 —— 用于创建新线程的工厂。使用自定义 ThreadFactory 可以自定义线程的名称、优先级、守护进程状态等。
  • 「handler」: 拒绝策略 —— 当线程池和工作队列都满了时,定义任务的拒绝策略。例如,ThreadPoolExecutor.AbortPolicy 是一个拒绝策略,它将抛出 RejectedExecutionException

ThreadPoolExecutor 执行流程

线程池的工作流程大致如下:

  1. 「新任务提交」: 当一个新任务被提交到线程池时,线程池会根据当前线程数量和工作队列状态采取以下行动之一:
  • 如果当前运行的线程数少于 corePoolSize,则创建并启动一个新线程来处理任务,即使其他工作线程处于空闲状态。
  • 如果运行的线程数等于或大于 corePoolSize,则将任务添加到工作队列。
  • 如果工作队列已满,且运行的线程数少于 maximumPoolSize,则创建并启动一个新线程来处理任务。
  • 如果工作队列已满,且运行的线程数等于 maximumPoolSize,则根据拒绝策略处理无法执行的任务。
  1. 「任务执行」: 线程池中的线程会从工作队列中取出任务并执行它们。一旦线程完成了任务,它会再次从队列中获取下一个任务(如果有的话)。
  2. 「线程终止」: 当一个线程没有任务执行,并且超过了 keepAliveTime,如果当前运行的线程数超过 corePoolSize,这个线程将被终止,以减少资源消耗。
  3. 「线程池关闭」: 当我们调用 shutdown() 方法时,线程池将不再接受新任务,但会继续处理工作队列中的所有剩余任务。调用 shutdownNow() 方法将尝试停止所有正在执行的任务,并停止处理工作队列中的任务。

通过合理配置这些参数,可以创建一个既能够处理动态变化的负载,又能够有效管理系统资源的线程池。

相关文章
|
3月前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
7月前
|
存储 Java
Java中带返回值方法的定义与调用技术
Java中带返回值方法的定义与调用技术
106 1
|
7月前
|
安全 Java
【亮剑】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果
【4月更文挑战第30天】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果。`Future`接口提供`isDone()`、`get()`、`get(timeout, unit)`和`cancel(mayInterruptIfRunning)`等方法。`FutureTask`是`Future`的实现类,可作为`Runnable`执行并返回结果。
75 1
|
7月前
|
Java API
线程池(关于变量捕获、线程数、针对ThreadPoolExecutor的构造方法参数的解释、自实现线程池)
线程池(关于变量捕获、线程数、针对ThreadPoolExecutor的构造方法参数的解释、自实现线程池)
|
缓存 Java 数据库连接
线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池
上面只是提到了对于Thread执行任务的一种动态实现方法,肯定还有其他的。 那么动态实现有什么好处呢? 当我们有很多个任务的时候,我们如果一直使用new,再让gc的话,那么对于系统资源的消耗无疑是巨大的。 那么这个时候,如果我们固定一下,专门拿几个线程来处理并发任务呢?但是当并发任务很多又该怎么办? 这个时候就引入了池化思想 —— Pool 什么是池? 在学JDBC的时候我们知道了连接池,在学Spring的时候,我们又接触到了对象池。 其实按理来说线程池应该是大家在初学JavaSE的时候应该就遇到的,这里我们再来讲一下。 线程池,就是用一个容器来管理线程,这个容器叫做池(Poo
117 0
线程的创建、Lambda函数式接口?Runnable和Callable之间的适配?动态修改线程任务?这里带你图解Java线程池
|
存储 Java
线程池的核心参数和执行流程
本章主要讲解了线程池的核心参数和执行流程
131 0
|
调度
Thread 类中的 yield()方法有什么作用?
Thread 类中的 yield()方法有什么作用?
161 0
|
Java Spring 容器
判断线程池是否全部完成的 5 种方法,还有谁不会?
判断线程池是否全部完成的 5 种方法,还有谁不会?
265 0
java基础学习 数组,循环,变量,函数加载情况先后顺序,方法定义
java基础学习 数组,循环,变量,函数加载情况先后顺序,方法定义
java基础学习 数组,循环,变量,函数加载情况先后顺序,方法定义
|
Java
Java中的方法的概念及无参、带参、带返回值方法定义和调用
方法的概念及无参、带参、带返回值方法定义和调用的简单示例
234 0
Java中的方法的概念及无参、带参、带返回值方法定义和调用