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

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

相关推荐
丶西红柿丶1 分钟前
python-带参数和不带参数的装饰器
后端
无巧不成书02182 分钟前
Unicode编码机制全解析:从核心原理到Java 实战
java·开发语言·java字符编码·unicode 15.1码点
楼田莉子2 分钟前
设计模式:构造器模式
开发语言·c++·后端·学习·设计模式
mu_guang_6 分钟前
计算机体系结构3-cache一致性和内存一致性的区别
java·开发语言·计算机体系结构
海兰9 分钟前
使用 Spring AI 打造企业级 RAG 知识库第一部分:核心基础
java·人工智能·spring
恼书:-(空寄11 分钟前
责任链模式实现流程动态编排
java·责任链模式
星原望野11 分钟前
java:volatile关键字的作用
java·开发语言·volatile
XiYang-DING19 分钟前
【Java】Map和Set
java·开发语言
菜菜小狗的学习笔记22 分钟前
八股(二)Java集合
java·开发语言
星乐a23 分钟前
String 不可变性与常量池深度解析
java·开发语言