# Java线程池详细介绍 ## 1. 线程池概述 ### 1.1 什么是线程池 线程池(Thread Pool)是一种多线程处理形式,它预先创建一组线程并放入"池"中管理。当有任务到来时,从池中取出空闲线程执行任务,任务完成后线程返回池中等待下次使用,而不是立即销毁。 ### 1.2 为什么需要线程池 在Java中直接创建线程存在以下问题: - 线程创建和销毁开销大 - 无限制创建线程可能导致系统资源耗尽 - 缺乏统一管理,难以监控和调优 线程池的优势: - **降低资源消耗**:复用已创建的线程 - **提高响应速度**:任务到达时线程已存在 - **提高线程可管理性**:统一分配、调优和监控 - **提供更多功能**:支持定时/周期执行等 ## 2. Java线程池核心类 ### 2.1 Executor框架 Java通过`java.util.concurrent`包提供线程池支持,核心接口和类包括: - `Executor`:最基础的执行接口 - `ExecutorService`:扩展了Executor,提供更丰富的功能 - `ThreadPoolExecutor`:最灵活的线程池实现类 - `Executors`:线程池工厂类,提供常用配置 ### 2.2 核心实现类 `ThreadPoolExecutor`是线程池的核心实现类,其构造函数如下: ```java public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize:核心线程数
allowCoreThreadTimeOut
maximumPoolSize:最大线程数
keepAliveTime:空闲线程存活时间
unit:存活时间单位
workQueue
:任务队列,常用实现有: - ArrayBlockingQueue
:有界数组队列 - LinkedBlockingQueue
:可设置容量的链表队列 - SynchronousQueue
:不存储元素的同步队列 - PriorityBlockingQueue
:带优先级的无界队列
threadFactory
:用于创建新线程,可自定义线程名称、优先级等:
ThreadFactory customFactory = new ThreadFactory() { private AtomicInteger count = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("Worker-" + count.incrementAndGet()); t.setPriority(Thread.NORM_PRIORITY); return t; } };
handler
:当线程池和队列都饱和时的处理策略,内置策略有: - AbortPolicy
(默认):抛出RejectedExecutionException - CallerRunsPolicy
:由调用者线程执行任务 - DiscardPolicy
:直接丢弃任务 - DiscardOldestPolicy
:丢弃队列中最老的任务
提交任务后,首先判断核心线程是否已满
工作队列满时,判断线程数是否达到最大线程数
线程执行完任务后
graph TD A[提交任务] --> B{核心线程<br>是否已满?} B -->|否| C[创建核心线程执行] B -->|是| D{工作队列<br>是否已满?} D -->|否| E[任务入队列等待] D -->|是| F{线程数是否<br>达到最大值?} F -->|否| G[创建非核心线程执行] F -->|是| H[执行拒绝策略]
FixedThreadPool(固定大小线程池)
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
CachedThreadPool(可缓存线程池)
ExecutorService cachedPool = Executors.newCachedThreadPool();
SingleThreadExecutor(单线程池)
ExecutorService singleThread = Executors.newSingleThreadExecutor();
ScheduledThreadPool(定时线程池)
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
推荐使用ThreadPoolExecutor
构造函数创建:
ThreadPoolExecutor customPool = new ThreadPoolExecutor( 2, // corePoolSize 5, // maximumPoolSize 60, // keepAliveTime TimeUnit.SECONDS, new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
CPU密集型任务:
IO密集型任务:
监控关键指标:
threadPool.getPoolSize(); // 当前线程数 threadPool.getActiveCount(); // 活动线程数 threadPool.getCompletedTaskCount(); // 已完成任务数 threadPool.getTaskCount(); // 总任务数
动态调整参数(需要自定义线程池):
threadPool.setCorePoolSize(10); threadPool.setMaximumPoolSize(20);
executor.shutdown(); // 温和关闭 executor.shutdownNow(); // 立即关闭
自定义拒绝策略示例:
RejectedExecutionHandler customHandler = (r, executor) -> { // 记录日志 logger.warn("Task rejected: " + r.toString()); // 重试机制 if (!executor.isShutdown()) { executor.getQueue().put(r); } };
确保任务正确处理异常:
executor.submit(() -> { try { // 业务代码 } catch (Exception e) { logger.error("Task failed", e); } });
ThreadPoolExecutor
提供可重写方法:
protected void beforeExecute(Thread t, Runnable r) { // 任务执行前 } protected void afterExecute(Runnable r, Throwable t) { // 任务执行后 } protected void terminated() { // 线程池终止后 }
Java 7+引入的Work-Stealing线程池:
ForkJoinPool forkJoinPool = new ForkJoinPool(4); forkJoinPool.invoke(new RecursiveAction() { @Override protected void compute() { // 分治任务 } });
Java线程池是并发编程的核心组件,合理使用可以: - 显著提高系统性能 - 降低资源消耗 - 提高系统稳定性
关键点: 1. 理解核心参数和工作原理 2. 根据任务类型选择合适的配置 3. 做好监控和异常处理 4. 遵循最佳实践避免常见陷阱
通过本文的介绍,希望读者能够深入理解Java线程池的机制,并在实际开发中灵活运用这一强大工具。 “`
这篇文章约2900字,涵盖了Java线程池的核心概念、实现原理、使用方法和最佳实践,采用Markdown格式编写,包含代码示例和流程图说明。您可以根据需要进一步调整内容或添加具体案例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。