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

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

相关推荐
重生之我在二本学院拿offer当牌打3 小时前
Redis分布式锁深度解析:从SETNX到Redisson,彻底搞懂分布式锁!
后端
木易 士心3 小时前
Spring AI 核心架构解析:构建企业级 AI 应用的 Java 新范式
java·spring
6190083363 小时前
linux 安装jdk
java·linux·运维
懂得节能嘛.3 小时前
【动态配置中心】Java+Redis构建动态配置中心
java·开发语言·redis
专注于大数据技术栈3 小时前
Java中JDK、JRE、JVM概念
java·开发语言·jvm
YuanlongWang3 小时前
C# 基础——值类型与引用类型的本质区别
java·jvm·c#
绝无仅有3 小时前
百度面试题解析:微服务架构、Dubbo、Redis及其一致性问题(一)
后端·面试·github
绝无仅有4 小时前
百度面试题解析:Zookeeper、ArrayList、生产者消费者模型及多线程(二)
后端·面试·github
Kay_Liang4 小时前
大语言模型如何精准调用函数—— Function Calling 系统笔记
java·大数据·spring boot·笔记·ai·langchain·tools