java线程池任务提交后严格遵循四步判定流程:先判线程数是否小于corepoolsize,是则创建核心线程执行;否则尝试入队;若队列满且线程数小于maximumpoolsize,则创建非核心线程;否则触发拒绝策略。

Java 线程池任务提交后,并不靠“智能调度算法”分配线程,而是严格遵循一套四步判定流程。这个流程由当前线程数、队列状态和配置参数共同驱动,每一步都是确定性的条件判断,没有动态负载均衡或优先级抢占。
核心线程优先创建
调用 execute() 提交任务时,线程池首先检查运行中的线程数是否小于 corePoolSize。若是,立即创建一个新核心线程执行该任务,且不入队。这一设计确保核心线程能快速响应初始流量,同时避免无谓的排队开销。
- 创建过程需获取全局锁(mainLock),保证线程安全
- 核心线程默认长期存活,即使空闲也不会被回收(除非启用 allowCoreThreadTimeOut)
- 适用于稳定、持续的任务流,比如定时心跳、常驻监听等
任务优先入队而非扩容
当运行线程数已达 corePoolSize,线程池不再新建线程,而是尝试将任务加入 workQueue。这是关键设计取舍:入队成本远低于创建线程(无需加锁、不触发上下文切换、不占用额外栈内存)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 入队前会检查线程池是否处于 RUNNING 状态
- 入队成功后,还会做一次双重检查(double-check)——确认状态未变,防止任务被无声丢弃
- 队列类型直接影响行为:有界队列(如 ArrayBlockingQueue)可防 OOM;无界队列(如 LinkedBlockingQueue)易掩盖容量风险
非核心线程作为弹性缓冲
只有当队列已满,且当前线程数仍小于 maximumPoolSize 时,才创建非核心线程执行任务。这类线程是“临时工”,空闲超过 keepAliveTime 就会被回收。
- 创建同样需要获取全局锁,因此高并发下可能成为瓶颈
- 它的存在只为应对瞬时峰值,不是常态承载主力
- 若 corePoolSize 设置过小、队列过大,可能导致非核心线程长期闲置,资源浪费
拒绝策略是最后的安全阀
当队列满 + 线程数已达 maximumPoolSize,线程池无法再接纳新任务,此时必须触发 RejectedExecutionHandler。这不是异常,而是明确的设计决策。
- 四种内置策略各具用途:Abort(抛异常)、CallerRuns(由提交线程自执行)、Discard(静默丢弃)、DiscardOldest(丢最老任务)
- 生产环境建议自定义策略,比如记录日志、降级处理、或转发至异步重试队列
- 拒绝发生往往意味着资源配置与实际负载不匹配,应作为调优的重要信号
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










