首页 > 编程语言 >揭秘ThreadPoolExecutor:深度解析Java线程池的艺术与源码之美

揭秘ThreadPoolExecutor:深度解析Java线程池的艺术与源码之美

时间:2024-06-18 18:28:47浏览次数:28  
标签:Java corePoolSize 之美 maximumPoolSize 任务 源码 线程 workQueue ThreadPoolExecutor

1. 线程池概述

在Java中,线程池(ThreadPool)是一种管理线程的技术,通过预先创建并管理一组线程,来减少频繁创建和销毁线程所带来的开销,从而提高系统的响应速度和吞吐量。ThreadPoolExecutor是Java并发包java.util.concurrent中的一个核心类,它提供了丰富的线程池功能。


2. ThreadPoolExecutor的核心概念

  • 线程池状态:ThreadPoolExecutor有五种状态,包括RUNNING、SHUTDOWN、STOP、TIDYING和TERMINATED。这些状态之间通过调用shutdown()和shutdownNow()等方法进行转换。
  • 核心参数
    • corePoolSize:线程池中核心线程数的最大值。
    • maximumPoolSize:线程池中能拥有的最大线程数。
    • workQueue:用于缓存任务的阻塞队列。
    • keepAliveTime和TimeUnit:表示非核心线程的空闲存活时间及其时间单位。
    • handler:当线程池无法处理新任务时所使用的拒绝策略。

3. ThreadPoolExecutor的工作原理

当向线程池提交一个任务时,ThreadPoolExecutor会按照以下步骤处理:

  1. 判断当前线程数:如果线程池中的线程数小于corePoolSize,则创建新线程执行任务。
  2. 判断工作队列:如果线程数已达到corePoolSize,则将任务加入workQueue中等待。
  3. 判断最大线程数:如果workQueue已满,且线程数小于maximumPoolSize,则创建新线程执行任务。
  4. 拒绝任务:如果线程数已达到maximumPoolSize,且workQueue已满,则根据handler指定的策略拒绝新任务。

4. 源码分析

4.1 核心字段

ThreadPoolExecutor 类中定义了一些关键的字段,这些字段对于理解其工作原理至关重要:

  • ctl:一个 AtomicInteger 类型的字段,用于保存线程池的状态和线程数量。高三位表示线程池的状态,低29位表示线程数量。
  • workQueue:一个阻塞队列,用于存放待执行的任务。
  • corePoolSize:核心线程数。
  • maximumPoolSize:最大线程数。
  • keepAliveTime:非核心线程的空闲存活时间。
  • threadFactory:用于创建新线程的线程工厂。
  • handler:拒绝策略处理器,当线程池无法处理新任务时调用。

4.2 构造方法

构造方法用于初始化线程池的各个参数:

public ThreadPoolExecutor(int corePoolSize,  
                          int maximumPoolSize,  
                          long keepAliveTime,  
                          TimeUnit unit,  
                          BlockingQueue<Runnable> workQueue,  
                          ThreadFactory threadFactory,  
                          RejectedExecutionHandler handler) {
     
    // ... 省略了部分参数校验和初始化代码 ...  
    this.corePoolSize = corePoolSize;  
    this.maximumPoolSize = maximumPoolSize;  
    this.workQueue = workQueue;  
    // ... 省略其他字段初始化 ...  
}

4.3 任务提交与执行

execute 方法是提交任务到线程池的主要入口:

public void execute(Runnable command) {
     
    if (command == null)  
        throw new NullPointerException();  
    /*  
     * Proceed in 3 steps:  
     *  
     * 1. If fewer than corePoolSize threads are running, try to  
     * start a new thread with the given command as its first  
     * task.  The call to addWorker atomically checks runState and  
     * workerCount, and so prevents false alarms that would add  
     * threads when it shouldn't, by returning false.  
     *  
     * 2. If a task can be successfully queued, then we still need  
     * to double-check whether we should have added a thread  
     * (because existing ones died since last checking) or that  
     * the pool shut down since entry into this method. So we  
     * recheck state and if necessary roll back the enqueuing if  
     * stopped, or start a new thread if there are none.  
     *  
     * 3. If we cannot queue task, then we try to add a new  
     * thread.  If it fails, we know we are shut down or saturated  
     * and so reject the task.  
     */  
    int c = ctl.get();  
    if (workerCountOf(c) < corePoolSize) {
     
        if (addWorker(command, true))  
            return;  
        c = ctl.get();  
    }  
    if (isRunning(c) && workQueue.offer(command)) {
     
        int recheck = ctl.get(

标签:Java,corePoolSize,之美,maximumPoolSize,任务,源码,线程,workQueue,ThreadPoolExecutor
From: https://blog.csdn.net/m0_51176516/article/details/139741705

相关文章

  • JavaScript 的Blob 对象详解
    JavaScript的Blob对象详解:https://blog.csdn.net/qq_41152573/article/details/136225387?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171870454816800227415776%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=17187045481680......
  • 详谈JavaScript 二进制家族:Blob、File、FileReader、ArrayBuffer、Base64
    详谈JavaScript二进制家族:Blob、File、FileReader、ArrayBuffer、Base64:https://blog.csdn.net/weixin_43025151/article/details/129743443?ops_request_misc=&request_id=&biz_id=102&utm_term=JavaScript%E4%B8%AD%E7%9A%84Blob%E4%BD%A0%E7%9F%A5%E9%81%93%E5%A4%9A%E......
  • 【OpenGauss源码学习 —— (ALTER TABLE(列存删除列))】
    ALTERTABLE(列存删除列)ATExecDropColumn函数1.检查是否是列存储表:2.获取子表的递归处理:3.处理子表的列删除:4.删除列存储表的列信息:5.处理MOT表:6.处理TSDB表:CStoreRelDropColumn函数代码修改要点CStoreDropColumnInCuDesc函数InsertStorageIntoPendingList......
  • 毕业设计:人事管理系统,基于java+springboot+mysql
     一、前言介绍          困扰管理层的许多问题当中,人事管理是一定不敢忽视的一块。但是管理好人事又面临很多麻烦需要解决,例如有几个方面:第一,公司往往员工人数都比较多,如何保证能够管理到每一员工;第二,如何在工作琐碎,记录繁多的情况下将人事变动的情况反应......
  • 全域外卖系统源码在哪搭建?哪家公司的系统源码最值得推荐
    随着全域外卖的兴起,全域外卖系统源码搭建逐渐在众多全域外卖赛道的入局方式中脱颖而出。但是,就目前多个创业者社群就这一话题的讨论程度来看,绝大多数创业者对于全域外卖系统源码搭建模式的了解都仅仅停留在“是什么”层面,而对于全域外卖系统源码在哪搭建等问题知之甚少。当......
  • Flink1.17.0-报错: java.lang.NoSuchMethodError: org.apache.kafka.clients.admin.De
    背景:启动Flink的sql-client.sh,创建Kafka的source端表,然后查询Kafka的数据时报错。报错信息:2024-06-1816:10:12org.apache.flink.util.FlinkException:GlobalfailuretriggeredbyOperatorCoordinatorfor'Source:kafka_rmc_cust_analog_u[1]'(operatorbc764cd8ddf7a0c......
  • java freemarker实现单元格动态合并
    在Java项目中,使用FreeMarker模板引擎来动态生成Excel文件,并实现单元格的动态合并(特别是行合并)。可以通过以下步骤来完成:1.准备数据模型        需要准备一个合适的数据模型,该模型应能表示出哪些单元格需要合并。        例如,如果想要根据某一列的值来决定......
  • 免费分享一套SpringBoot+Vue房地产销售管理系统【论文+源码+SQL脚本+PPT+开题报告】,帅
    大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue房地产销售管理系统,分享下哈。项目视频演示【免费】SpringBoot+Vue房地产销售管理系统Java毕业设计_哔哩哔哩_bilibili【免费】SpringBoot+Vue房地产销售管理系统Java毕业设计项目来自互联网,免费分享,仅供学习交流......
  • 采用java语言+Redis+RabbitMQ开发的 门诊his系统源码 一站式的门诊his系统 门诊业务流
    采用java语言+Redis+RabbitMQ开发的门诊his系统源码一站式的门诊his系统门诊业务流程医院信息系统(HIS系统)门诊业务是医院信息化建设的重要组成部分之一,它涵盖了医院门诊部门涉及的各项业务。HIS系统门诊业务的实施,可以实现医院门诊业务的信息化管理和数据化处理,提高医疗服......
  • 2024最新多语言UI界面注流钱包盗U授机源码
    环境:Linux系统进入宝塔安装环境:Nginx1.22.1MySQL8.0php7.4phpMyAdmin5.2 按照说明去安装环境,如果没有找到MySQL8.0版本去"软件商店"搜索Mysql切换至8.01.上传开源源码2.上传数据库文件3.上传猴导入数据库文件4.修改数据库文件/application/database.php ,填写数......