Java线程池原理概述

Java线程池详解

一、使用方式
  1. 创建线程池
java 复制代码
// 使用Executors工厂类
ExecutorService fixedPool = Executors.newFixedThreadPool(5); // 固定大小线程池
ExecutorService cachedPool = Executors.newCachedThreadPool(); // 弹性线程池
ExecutorService scheduledPool = Executors.newScheduledThreadPool(3); // 定时任务线程池

// 手动配置(推荐)
ThreadPoolExecutor customPool = new ThreadPoolExecutor(
    4, // 核心线程数
    10, // 最大线程数
    60, // 空闲线程存活时间(秒)
    TimeUnit.SECONDS, // 时间单位
    new ArrayBlockingQueue<>(100) // 任务队列
);
  1. 提交任务
java 复制代码
// 执行无返回值任务
executor.execute(() -> {
    System.out.println("Task running in: " + Thread.currentThread().getName());
});

// 提交有返回值任务
Future<String> future = executor.submit(() -> {
    return "Result from " + Thread.currentThread().getName();
});
System.out.println(future.get()); // 获取结果
  1. 关闭线程池
java 复制代码
executor.shutdown(); // 平缓关闭(执行完队列任务)
executor.shutdownNow(); // 立即关闭(尝试中断所有线程)
二、底层原理
  1. 核心组件

    • 工作队列:存储待执行任务(阻塞队列实现)
    • 工作线程集合HashSet<Worker>
    • 线程工厂ThreadFactory 创建新线程
    • 拒绝策略:当队列满时的处理机制
  2. 任务执行流程

    graph TD A[提交任务] --> B{核心线程空闲?} B -->|是| C[立即执行] B -->|否| D{队列未满?} D -->|是| E[加入队列] D -->|否| F{可创建新线程?} F -->|是| G[创建新线程执行] F -->|否| H[触发拒绝策略]
  3. 线程生命周期管理

    • 核心线程常驻(除非设置allowCoreThreadTimeOut
    • 非核心线程超时销毁
    • 线程通过Worker封装实现任务循环:
    java 复制代码
    while (task != null || (task = getTask()) != null) {
        task.run(); // 实际执行任务
    }
三、自定义线程使用
  1. 自定义线程工厂
java 复制代码
class CustomThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    
    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r, "custom-pool-" + 
            poolNumber.getAndIncrement() + "-thread");
    }
}

// 使用自定义工厂
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    4, 10, 60, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(),
    new CustomThreadFactory()  // 注入工厂
);
  1. 自定义拒绝策略
java 复制代码
class CustomRejectPolicy implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // 自定义处理逻辑(如记录日志/存入数据库)
        System.err.println("Task rejected: " + r.toString());
    }
}

// 配置拒绝策略
executor.setRejectedExecutionHandler(new CustomRejectPolicy());
  1. 扩展线程池行为
java 复制代码
class MonitoringThreadPool extends ThreadPoolExecutor {
    // 重写钩子方法
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        System.out.println("Start: " + r);
    }
    
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        System.out.println("Finish: " + r);
    }
}
最佳实践建议
  1. 避免使用Executors.newFixedThreadPool()可能引发OOM(默认使用无界队列)
  2. 合理配置参数:
    • CPU密集型:核心线程数 ≈ CPU核数
    • IO密集型:核心线程数 ≈ CPU核数 * 2
  3. 使用ThreadPoolExecutor而非ExecutorService接口以便访问扩展方法
  4. 重要任务建议使用有界队列+自定义拒绝策略
相关推荐
阿拉丁的梦1 小时前
教程1:用vscode->ptvsd-创建和调试一个UI(python)-转载官方翻译(有修正)
开发语言·python
木宇(记得热爱生活)2 小时前
一键搭建开发环境:制作bash shell脚本
开发语言·bash
麦兜*2 小时前
Spring Boot 集成 Docker 构建与发版完整指南
java·spring boot·后端·spring·docker·系统架构·springcloud
Cisyam^2 小时前
Go环境搭建实战:告别Java环境配置的复杂
java·开发语言·golang
CHENFU_JAVA2 小时前
使用EasyExcel实现Excel单元格保护:自由锁定表头和数据行
java·excel
IAR Systems3 小时前
在IAR Embedded Workbench for Arm中实现Infineon TRAVEO™ T2G安全调试
开发语言·arm开发·安全·嵌入式软件开发·iar
青云交3 小时前
Java 大视界 -- 基于 Java 的大数据实时流处理在智能电网分布式电源接入与电力系统稳定性维护中的应用(404)
java·大数据·分布式·智能电网·flink 实时流处理·kafka 数据采集·iec 61850 协议
jayzhang_3 小时前
SPARK入门
大数据·开发语言
蹦极的考拉3 小时前
网站日志里面老是出现{pboot:if((\x22file_put_co\x22.\x22ntents\x22)(\x22temp.php\x22.....
android·开发语言·php
fured3 小时前
[调试][实现][原理]用Golang实现建议断点调试器
开发语言·后端·golang