Java 线程池详解

Java 线程池详解
从原理到实战,全面掌握线程池核心技能

一、线程池核心原理

提交任务

线程池

任务队列
workQueue

核心线程1

核心线程2

核心线程N

临时线程1

临时线程2

任务

线程池 = 任务队列 + 工作线程

组件作用
任务队列缓存待执行任务
工作线程从队列取任务执行
线程管理控制线程数量、回收空闲线程

二、线程池处理流程

提交任务

线程数 < corePoolSize?

创建新线程

队列已满?

执行任务

加入队列等待

线程数 < maximumPoolSize?

创建临时线程

触发拒绝策略

拒绝任务

执行流程:

  1. 线程数 < corePoolSize → 创建新线程执行
  2. 线程数 >= corePoolSize → 任务加入队列
  3. 队列满 + 线程数 < maximumPoolSize → 创建临时线程
  4. 队列满 + 线程数 = maximumPoolSize → 拒绝任务

三、线程池 7 大参数

newThreadPoolExecutor(int corePoolSize,// 1. 核心线程数int maximumPoolSize,// 2. 最大线程数long keepAliveTime,// 3. 空闲线程存活时间TimeUnit unit,// 4. 时间单位BlockingQueue<Runnable> workQueue,// 5. 任务队列ThreadFactory threadFactory,// 6. 线程工厂RejectedExecutionHandler handler // 7. 拒绝策略);
参数说明示例值
corePoolSize核心线程数,常驻线程数10
maximumPoolSize最大线程数,弹性扩展上限50
keepAliveTime空闲线程存活时间60
unit时间单位TimeUnit.SECONDS
workQueue任务队列new ArrayBlockingQueue<>(100)
threadFactory线程创建工厂Executors.defaultThreadFactory()
handler拒绝策略new ThreadPoolExecutor.AbortPolicy()

四、任务队列选择

队列类型特点适用场景
ArrayBlockingQueue有界队列,需指定容量限流场景
LinkedBlockingQueue无界队列,默认 Integer.MAX_VALUE任务堆积风险
SynchronousQueue无容量,直接交付快速响应场景
DelayedWorkQueue延迟队列定时任务
// 有界队列(推荐)newArrayBlockingQueue<>(100)// 无界队列(谨慎使用)newLinkedBlockingQueue<>()// 同步队列(适合耗时短的任务)newSynchronousQueue<>()

五、拒绝策略

策略行为适用场景
AbortPolicy抛异常默认,需业务处理
CallerRunsPolicy调用者线程执行缓冲压力,慎用
DiscardPolicy静默丢弃日志等非核心任务
DiscardOldestPolicy丢弃最老任务优先处理新任务
// 默认:抛异常newAbortPolicy()// 调用者执行newCallerRunsPolicy()// 丢弃任务newDiscardPolicy()// 丢弃最老任务newDiscardOldestPolicy()

六、线程工厂

ThreadFactory factory =newThreadFactory(){privateAtomicInteger count =newAtomicInteger(1);@OverridepublicThreadnewThread(Runnable r){Thread thread =newThread(r); thread.setName("MyThread-"+ count.getAndIncrement()); thread.setDaemon(false);// 非守护线程return thread;}};

常用配置:

  • 线程命名
  • 守护线程设置
  • 线程优先级

七、Executors 工具类

方法说明风险
newFixedThreadPool(n)固定 n 线程无界队列,OOM
newSingleThreadExecutor()单线程无界队列,OOM
newCachedThreadPool()弹性扩展最大 Integer.MAX_VALUE
newScheduledThreadPool(n)定时任务无界队列,OOM

阿里巴巴规范:不推荐使用!

// 不推荐:可能 OOMExecutorService pool =Executors.newFixedThreadPool(10);// 推荐:手动配置ExecutorService pool =newThreadPoolExecutor(10,50,60L,TimeUnit.SECONDS,newArrayBlockingQueue<>(100),newThreadPoolExecutor.AbortPolicy());

八、线程池状态

创建

shutdown()

shutdownNow()

队列空 + 无活跃线程

无活跃线程

terminated()执行完毕

RUNNING

SHUTDOWN

STOP

TIDYING

TERMINATED

状态说明
RUNNING111接收新任务,执行任务
SHUTDOWN000不接收新任务,执行已提交任务
STOP001不接收新任务,不执行已提交任务
TIDYING010任务执行完毕,准备终止
TERMINATED011完全终止

九、实战配置

1. CPU 密集型任务

// CPU 核心数 + 1int cpuCores =Runtime.getRuntime().availableProcessors();newThreadPoolExecutor( cpuCores +1, cpuCores +1,0L,TimeUnit.MILLISECONDS,newLinkedBlockingQueue<>(1000));

2. IO 密集型任务

// CPU 核心数 * 2int cpuCores =Runtime.getRuntime().availableProcessors();newThreadPoolExecutor( cpuCores *2, cpuCores *2,60L,TimeUnit.SECONDS,newLinkedBlockingQueue<>(1000));

3. 混合型任务

newThreadPoolExecutor( cpuCores +1, cpuCores *2,60L,TimeUnit.SECONDS,newArrayBlockingQueue<>(500));

十、线程池监控

1. 常用监控方法

ThreadPoolExecutor executor =newThreadPoolExecutor(...);// 活跃线程数 executor.getActiveCount();// 队列任务数 executor.getQueue().size();// 已完成任务数 executor.getCompletedTaskCount();// 总任务数 executor.getTaskCount();// 线程池是否Terminated executor.isTerminated();

2. 线程池监控示例

publicclassThreadPoolMonitor{publicstaticvoidprintStatus(ThreadPoolExecutor executor){System.out.println("====================");System.out.println("线程池大小: "+ executor.getPoolSize());System.out.println("活跃线程数: "+ executor.getActiveCount());System.out.println("队列任务数: "+ executor.getQueue().size());System.out.println("已完成任务: "+ executor.getCompletedTaskCount());System.out.println("总任务数: "+ executor.getTaskCount());System.out.println("====================");}}

十一、优雅关闭线程池

ThreadPoolExecutor executor =newThreadPoolExecutor(...);// 1. 拒绝新任务 executor.shutdown();// 2. 等待任务完成(带超时)if(!executor.awaitTermination(60,TimeUnit.SECONDS)){// 3. 强制中断 executor.shutdownNow();}// 或者直接暴力关闭 executor.shutdownNow();

关闭原则:

  1. shutdown() 拒绝新任务
  2. 等待任务完成或超时
  3. 超时后 shutdownNow() 强制中断

十二、常见问题

1. 线程池参数设置多大?

任务类型推荐线程数
CPU 密集型CPU 核心数 + 1
IO 密集型CPU 核心数 * 2
混合型CPU 核心数 + 1 ~ CPU 核心数 * 2

2. 队列容量设置多大?

// 经验公式 队列容量 = 核心线程数 * 期望响应时间(秒)*2

3. 线程池会 OOM 吗?

会!常见原因:

  • LinkedBlockingQueue 无界队列堆积
  • 任务过多且执行慢
  • 拒绝策略不合理

解决:

  • 使用有界队列
  • 合理设置 maximumPoolSize
  • 监控队列大小

4. 核心线程会被回收吗?

默认不会!设置允许回收:

executor.allowCoreThreadTimeOut(true);

十三、总结

线程池核心

参数配置
core/max/queue

队列选择
Array/Linked/Synchronous

拒绝策略
4种策略

监控与调优

合理配置
避免 OOM

优雅关闭
防止任务丢失

核心要点:

要点说明
参数配置根据任务类型选择 core/max/queue
队列选择优先使用有界队列
拒绝策略根据业务选择合适的策略
监控定期监控队列大小、活跃线程数
关闭先 shutdown 再 awaitTermination

Read more

系统学习C++-第二十一讲-用哈希表封装 myunordered_map 和 myunordered_set

系统学习C++-第二十一讲-用哈希表封装 myunordered_map 和 myunordered_set

系统学习C++-第二十一讲-用哈希表封装 myunordered_map 和 myunordered_set * 1. 源码及框架分析 * 2. 模拟实现 unordered_map 和 unordered_set * 2.1 实现出复用哈希表的框架,并支持 insert * 2.2 支持 iterator 的实现 * 2.3 map 支持 ` [] ` * 2.4 unordered_map 和 unordered_set 代码实现 1. 源码及框架分析 SGI-STL30 版本源代码中没有 unordered_map 和 unordered_set ,SGI-STL30 版本是 C+

By Ne0inhk
【C++详解】C++ 智能指针:使用场景、实现原理与内存泄漏防治

【C++详解】C++ 智能指针:使用场景、实现原理与内存泄漏防治

文章目录 * 一、智能指针的使⽤场景分析 * 二、RAII和智能指针的设计思路 * 三、C++标准库智能指针的使⽤ * 四、智能指针的原理 * shared_ptr源码 * 五、shared_ptr和weak_ptr * shared_ptr循环引⽤问题 * weak_ptr * 六、内存泄漏 * 什么是内存泄漏,内存泄漏的危害 * 如何避免内存泄漏 一、智能指针的使⽤场景分析 我们知道C++是是公认的高效编程语言,其中一点原因就是C++手动内存管理(new/delete),避免了很多高级语言(如 Java、Python)的自动内存管理(垃圾回收)带来的额外开销,这也是一把双刃剑,这对C++程序员的要求就会更高,因为手动内存管理很容易出现内存泄漏的问题,我们之前的说法是尽可能小心,但是有些场景无法避免会出现内存泄漏(或者处理起来很麻烦)

By Ne0inhk
C++性能优化:提升代码执行效率的艺术

C++性能优化:提升代码执行效率的艺术

C++性能优化:提升代码执行效率的艺术 一、学习目标与重点 本章将深入探讨C++性能优化的核心知识,帮助你掌握提升代码执行效率的艺术。通过学习,你将能够: 1. 理解性能优化的基本概念,掌握性能分析的方法 2. 学会优化内存管理,减少内存泄漏和内存碎片 3. 理解CPU优化技巧,提高代码的执行速度 4. 学会优化I/O操作,提升文件和网络读写的效率 5. 培养性能优化思维,设计高效的代码 二、性能优化的基本概念 2.1 性能优化的原则 性能优化应该遵循以下原则: * 先测量后优化:在优化之前,必须先测量代码的性能,找出瓶颈所在 * 优化瓶颈:只优化对性能影响最大的部分 * 保持代码的可维护性:优化后的代码应该易于理解和维护 * 测试优化结果:优化后必须测试代码的正确性和性能提升效果 2.2 性能分析工具 常用的性能分析工具包括: * GProf:GNU的性能分析工具 * Valgrind:内存调试和性能分析工具

By Ne0inhk

Visual C++运行库修复完整解决方案:从故障排查到高效部署

Visual C++运行库修复完整解决方案:从故障排查到高效部署 【免费下载链接】vcredistAIO Repack for latest Microsoft Visual C++ Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 还在为"MSVCP140.dll丢失"或"VCRUNTIME140_1.dll未找到"这类错误头疼吗?作为支撑众多C++程序运行的核心组件,Visual C++ Redistributable的安装问题确实让不少用户感到困扰。本文将为您提供一套完整的Visual C++运行库修复方案,涵盖从基础排查到企业级部署的各个环节。 环境速查清单:准备工作一览 在开始修复之前,让我们先确认几个关键要素: 系统基础要求: * Windows XP

By Ne0inhk