Java线程池快速入门

前言

线程池(Thread Pool)是一种用于管理和复用线程的机制,它在多线程编程中被广泛使用,目的是提高系统性能、减少资源开销、控制并发数量。下面从三个方面详细解释:


一、线程池有什么用?

线程池的主要作用是:

  • 复用线程:避免频繁创建和销毁线程带来的开销。
  • 控制并发数量:防止因创建过多线程导致系统资源耗尽(如内存溢出、CPU 过载)。
  • 提高响应速度:任务提交后可以立即由已有线程执行,无需等待线程创建。
  • 统一管理线程:便于监控、调度、异常处理等。

二、线程池是怎么用?

1.创建线程池

示例(Java):

csharp 复制代码
ExecutorService pool = new ThreadPoolExecutor(
    2,                    // corePoolSize
    4,                    // maximumPoolSize
    60L, TimeUnit.SECONDS, // keepAliveTime
    new LinkedBlockingQueue<>(10), // workQueue
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
pool.submit(() -> System.out.println("Hello from thread pool"));

2.核心组件:

1.核心线程数(corePoolSize) :线程池中保持的最小线程数量,即使空闲也不会被回收, 不是初始化就创建:线程池刚创建时线程数为 0,直到第一个任务提交才开始创建,提交任务时,若当前线程数 < corePoolSize,则新建线程。

2.最大线程数(maximumPoolSize) :线程池允许创建的最大线程数量, 仅当 workQueue 已满且当前线程数 < maximumPoolSize 时,才会创建非核心线程。

3.任务队列(workQueue) :用于存放等待执行的任务,队列的类型决定线程池的行为模式。

4.拒绝策略(RejectedExecutionHandler) :当任务无法提交时(队列满 + 线程数达上限)的处理方式。

5.线程工厂(ThreadFactory) :用于自定义创建新线程的方式,给线程命名等。

6.空闲线程存活时间(keepAliveTime 7.单位unit) :超过核心线程数的线程在空闲多久后被回收。

3.工作流程:

  1. 提交任务
  2. 如果当前线程数 < corePoolSize,则创建一个新线程来执行任务(即使有空闲线程)。
  3. 如果当前线程数 ≥ corePoolSize,则将任务放入任务队列
  4. 如果队列已满,且当前线程数 < maximumPoolSize,则创建新线程执行任务。
  5. 如果队列已满,且线程数已达 maximumPoolSize,则触发拒绝策略(如抛异常、丢弃任务、由调用者线程执行等)。

4.提交任务

1.execute()(Runnable Command),无返回值

ini 复制代码
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(() -> {
    System.out.println("Hello from execute");
});

2.submit()(三种重载),有返回值

r 复制代码
Future<?> submit(Runnable task)
<T> Future<T> submit(Runnable task, T result)
<T> Future<T> submit(Callable<T> task)

5.常见线程池类型

  • newFixedThreadPool:固定大小线程池(core = max,无界队列)。
  • newCachedThreadPool:弹性线程池(core=0,max=Integer.MAX_VALUE,适合短任务)。
  • newSingleThreadExecutor:单线程池,保证任务顺序执行。
  • newScheduledThreadPool:支持定时/周期性任务。

6.关闭线程池

  1. shutdown() ------ 优雅关闭
  • 不再接受新任务,但继续执行已提交的任务(包括队列中等待的任务)。
  • 工作线程处理完所有任务后,会自动退出。
  • 线程池最终会进入 TERMINATED 状态。
  • 不会中断正在执行的任务。
  1. shutdownNow() ------ 立即关闭
  • 不再接受新任务。
  • 尝试中断所有正在执行的线程(通过 Thread.interrupt())。
  • 清空任务队列,并返回未执行的任务列表。
  • 正在执行的任务可能不会立即停止(如果任务不响应中断)。

结语

线程池是 Java 并发编程的基石,理解其参数含义、工作流程、拒绝策略与关闭机制 ,是编写高性能、高可用系统的关键。
"会用"不等于"用好" ------合理配置、监控告警、优雅关闭,才能真正发挥线程池的价值。

下一篇:《线程池十问》------深入原理与实战避坑指南。

相关推荐
TaiKuLaHa4 分钟前
Spring Bean的生命周期
java·后端·spring
刀法如飞37 分钟前
开箱即用的 DDD(领域驱动设计)工程脚手架,基于 Spring Boot 4.0.1 和 Java 21
java·spring boot·mysql·spring·设计模式·intellij-idea
我是苏苏42 分钟前
Web开发:C#通过ProcessStartInfo动态调用执行Python脚本
java·服务器·前端
JavaGuide1 小时前
SpringBoot 官宣停止维护 3.2.x~3.4.x!
java·后端
Victor3561 小时前
Hibernate(39)Hibernate中如何使用拦截器?
后端
Victor3561 小时前
Hibernate(40)Hibernate的命名策略是什么?
后端
tkevinjd2 小时前
动态代理
java
Knight_AL2 小时前
Spring 事务管理:为什么内部方法调用事务不生效以及如何解决
java·后端·spring
bcbnb2 小时前
iOS代码混淆技术深度实践:从基础到高级全面解析
后端