跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
线程池原理与使用
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本条目适用于Java 5及以上版本,部分特性需JDK 7+支持}} = 线程池原理与使用 = '''线程池(Thread Pool)'''是Java并发编程中管理线程生命周期的核心工具,通过复用已创建的线程减少资源消耗,提高系统响应速度。本文将深入解析其工作原理、参数配置及最佳实践。 == 核心概念 == 线程池解决两个关键问题: # '''线程生命周期开销''':避免频繁创建/销毁线程 # '''资源耗尽风险''':防止无限制创建线程导致OOM Java通过<code>java.util.concurrent.ExecutorService</code>接口及其实现类提供线程池支持。 == 线程池架构 == <mermaid> classDiagram Executor <|-- ExecutorService ExecutorService <|-- AbstractExecutorService AbstractExecutorService <|-- ThreadPoolExecutor ThreadPoolExecutor <|-- ScheduledThreadPoolExecutor ExecutorService <|-- ScheduledExecutorService </mermaid> == 核心参数解析 == 线程池通过<code>ThreadPoolExecutor</code>的7个参数控制行为: {| class="wikitable" |+ 线程池构造参数 ! 参数 !! 类型 !! 说明 |- | corePoolSize || int || 核心线程数(常驻线程) |- | maximumPoolSize || int || 最大线程数(含核心线程) |- | keepAliveTime || long || 非核心线程空闲存活时间(纳秒) |- | unit || TimeUnit || 存活时间单位 |- | workQueue || BlockingQueue<Runnable> || 任务队列 |- | threadFactory || ThreadFactory || 线程创建工厂 |- | handler || RejectedExecutionHandler || 拒绝策略 |} === 工作流程 === <mermaid> flowchart TD A[提交任务] --> B{核心线程已满?} B -->|否| C[创建核心线程执行] B -->|是| D{队列已满?} D -->|否| E[任务入队等待] D -->|是| F{线程数达最大值?} F -->|否| G[创建非核心线程执行] F -->|是| H[执行拒绝策略] </mermaid> 数学表达线程池状态转换: <math> \begin{cases} \text{activeThreads} \leq \text{corePoolSize} & \text{(仅核心线程工作)} \\ \text{corePoolSize} < \text{activeThreads} \leq \text{maximumPoolSize} & \text{(启用非核心线程)} \\ \text{activeThreads} = \text{maximumPoolSize} & \text{(触发拒绝策略)} \end{cases} </math> == 四种常用线程池 == Java通过<code>Executors</code>工厂类提供预配置线程池: {| class="wikitable" |+ 标准线程池对比 ! 类型 !! 实现方式 !! 特点 !! 适用场景 |- | FixedThreadPool || <code>new ThreadPoolExecutor(n, n, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())</code> || 固定大小队列无界 || CPU密集型任务 |- | CachedThreadPool || <code>new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>())</code> || 自动扩容线程 || 短生命周期任务 |- | SingleThreadExecutor || <code>new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())</code> || 单线程顺序执行 || 需要顺序执行的任务 |- | ScheduledThreadPool || <code>new ScheduledThreadPoolExecutor(corePoolSize)</code> || 支持定时/周期任务 || 定时任务调度 |} == 代码示例 == === 基础使用 === <syntaxhighlight lang="java"> // 创建固定大小线程池 ExecutorService pool = Executors.newFixedThreadPool(4); // 提交任务 Future<String> future = pool.submit(() -> { Thread.sleep(1000); return "Task completed"; }); // 获取结果 System.out.println(future.get()); // 输出: Task completed // 关闭线程池 pool.shutdown(); </syntaxhighlight> === 自定义线程池 === <syntaxhighlight lang="java"> ThreadPoolExecutor customPool = new ThreadPoolExecutor( 2, // 核心线程数 5, // 最大线程数 60, // 空闲时间 TimeUnit.SECONDS, new ArrayBlockingQueue<>(10), // 有界队列 new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 ); // 监控示例 System.out.println("Active threads: " + customPool.getActiveCount()); System.out.println("Queue size: " + customPool.getQueue().size()); </syntaxhighlight> == 拒绝策略 == 当线程池和队列都饱和时触发拒绝策略: {| class="wikitable" |+ 内置拒绝策略 ! 策略类 !! 行为 !! 类比 |- | AbortPolicy || 抛出RejectedExecutionException || 默认策略 |- | CallerRunsPolicy || 由调用者线程执行任务 || 同步降级 |- | DiscardPolicy || 静默丢弃任务 || 空实现 |- | DiscardOldestPolicy || 丢弃队列最老任务 || 队列淘汰 |} == 实际案例 == === Web服务器请求处理 === <syntaxhighlight lang="java"> // 模拟HTTP服务器 public class WebServer { private static final ThreadPoolExecutor workerPool = new ThreadPoolExecutor( 8, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadPoolExecutor.AbortPolicy()); public void handleRequest(HttpRequest request) { workerPool.execute(() -> { // 处理请求逻辑 processRequest(request); }); } } </syntaxhighlight> === 批量数据处理 === <syntaxhighlight lang="java"> // 并行处理百万级数据 List<Data> dataList = getHugeDataList(); // 获取数据 ExecutorService batchPool = Executors.newWorkStealingPool(); // JDK8+工作窃取池 List<CompletableFuture<Void>> futures = dataList.stream() .map(data -> CompletableFuture.runAsync(() -> processData(data), batchPool)) .collect(Collectors.toList()); // 等待所有任务完成 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); </syntaxhighlight> == 最佳实践 == # '''队列选择''': #* CPU密集型:使用有界队列(如ArrayBlockingQueue) #* IO密集型:使用无界队列(如LinkedBlockingQueue) # '''线程数设置''': #* CPU密集型:<code>N<sub>threads</sub> = N<sub>cores</sub> + 1</code> #* IO密集型:<code>N<sub>threads</sub> = N<sub>cores</sub> × (1 + WT/ST)</code>(WT:等待时间,ST:服务时间) # '''关闭规范''': <syntaxhighlight lang="java"> pool.shutdown(); // 温和关闭 if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow(); // 强制关闭 } </syntaxhighlight> == 常见问题 == {{Warning|以下为典型错误用法}} * '''内存泄漏''':未关闭线程池导致JVM无法退出 * '''队列堆积''':任务生产速度 > 消费速度导致OOM * '''死锁风险''':线程池任务又提交新任务到同一池 == 性能监控 == 通过扩展<code>ThreadPoolExecutor</code>实现监控: <syntaxhighlight lang="java"> class MonitorableThreadPool extends ThreadPoolExecutor { protected void beforeExecute(Thread t, Runnable r) { System.out.printf("Task start - Active: %d, Completed: %d%n", getActiveCount(), getCompletedTaskCount()); } } </syntaxhighlight> == 进阶知识 == * '''工作窃取算法''':<code>ForkJoinPool</code>的实现原理 * '''线程池预热''':提前启动核心线程<code>prestartAllCoreThreads()</code> * '''动态调参''':运行时修改<code>setCorePoolSize()</code> {{Note|在Spring框架中,推荐使用<code>ThreadPoolTaskExecutor</code>进行更便捷的配置和管理}} [[Category:计算机科学]] [[Category:面试技巧]] [[Category:Java并发编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)