java线程池

Java线程池是多线程编程中的核心组件,能够有效管理线程资源、提升系统性能。


一、为什么需要线程池?

  1. 降低资源消耗:避免频繁创建/销毁线程的开销
  2. 提高响应速度:任务到达时直接使用可用线程
  3. 统一管理:控制并发数量,避免资源耗尽
  4. 提供扩展性:支持任务队列、拒绝策略等灵活配置

二、核心实现类 ThreadPoolExecutor

//线程池三种常见的分类,三者底层都是通过new ThreadPoolExecutors()来实现的
public class ThreadPoolDemo1{
    public static void main(String[] args) {
        //1. 一池5线程
        ExecutorService threadPool1 = Executors.newFixedThreadPool(5);
        //2. 一池一线程
        ExecutorService threadPool2 = Executors.newSingleThreadExecutor();
        //3. 一池可扩容线程
        ExecutorService threadPool3 = Executors.newCachedThreadPool();
        try{
            for (int i = 0; i < 10; i++) {
                threadPool1.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "办理业务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭线程池(不关闭的话,程序一直运行下去)
            threadPool1.shutdown();
        }
    }
}
public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler
)
核心参数解析
参数说明
corePoolSize核心线程数(长期保留的线程)
maximumPoolSize最大线程数(包括核心线程和非核心线程)
keepAliveTime非核心线程的空闲存活时间
unit时间单位(TimeUnit.SECONDS等)
workQueue任务队列(BlockingQueue实现)
threadFactory线程创建工厂(可自定义线程名称、优先级等)
handler拒绝策略(当队列和线程池满时的处理策略)


三、线程池工作流程

  1. 提交任务时,优先使用核心线程执行
  2. 核心线程已满 → 任务进入阻塞队列等待
  3. 队列已满 → 创建非核心线程执行任务(直到达到最大线程数)
  4. 超过最大线程数 → 触发拒绝策略


四、拒绝策略(RejectedExecutionHandler)

  1. AbortPolicy(默认):抛出RejectedExecutionException
  2. CallerRunsPolicy:由提交任务的线程直接执行
  3. DiscardPolicy:静默丢弃被拒绝的任务
  4. DiscardOldestPolicy:丢弃队列中最旧的任务,重试提交当前任务
// 自定义拒绝策略示例
new ThreadPoolExecutor.AbortPolicy() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        // 自定义处理逻辑
    }
}


五、Executors工具类预定义线程池

方法特点潜在问题
newFixedThreadPool固定线程数,无界队列可能堆积大量任务导致OOM
newCachedThreadPool线程数无限制(60秒回收),适合短时异步任务可能创建过多线程导致资源耗尽
newSingleThreadExecutor单线程,保证任务顺序执行无界队列有OOM风险
newScheduledThreadPool支持定时/周期性任务复杂任务需谨慎使用

建议:生产环境推荐手动配置ThreadPoolExecutor参数

//自定义线程池
public class ThreadPoolDemo2 {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                //线程池的默认的工厂
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy()
        );
    }
}

六、线程池状态管理

  1. RUNNING:接受新任务,处理队列任务
  2. SHUTDOWN:不接受新任务,继续处理队列任务
  3. STOP:不接受新任务,不处理队列任务,中断进行中的任务
  4. TIDYING:所有任务终止,workerCount=0
  5. TERMINATED:terminated()方法执行完成
// 关闭线程池的正确方式
executor.shutdown();          // 优雅关闭
executor.shutdownNow();       // 立即中断(慎用)

七、最佳实践

  1. 合理配置参数
    • CPU密集型任务:corePoolSize = CPU核心数
    • IO密集型任务:corePoolSize = CPU核心数 * 2
  2. 使用有界队列(如ArrayBlockingQueue)避免OOM
  3. 自定义线程名称(通过ThreadFactory)方便问题排查
  4. 监控线程池状态(通过重写beforeExecute/afterExecute)
  5. 处理未捕获异常
executor.setRejectedExecutionHandler((r, e) -> 
    System.out.println("Task rejected: " + r));

八、常见问题

  1. 线程泄漏:忘记关闭线程池 → 使用try-with-resourcesfinally
  2. 任务堆积:合理设置队列容量和拒绝策略
  3. 上下文切换开销:避免过度配置线程数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值