Java线程池详解 - ThreadPoolExecutor

发布时间:2026/11/3 14:13:27

Java线程池详解 - ThreadPoolExecutor Android中经常出现一些任务不执行重新进入或杀掉进程又可以执行为什么要充分理解拒绝策略当线程池中的线程已满究竟是抛出异常try-catch还是丢弃任务还是其他的方法处理拒绝策略执行的条件线程池中的线程数量 最大线程数 任务队列如果任务队列的数量设置很大时间设置很长也没啥意义。比如设置100个1分钟。有些任务可能等待非常久才执行。ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)int corePoolSize, // 核心线程数定义线程池中始终保持存活的线程数量即使这些线程处于空闲状态。除非设置allowCoreThreadTimeOutexecutor.allowCoreThreadTimeOut(true); // 允许核心线程超时销毁int maximumPoolSize, // 最大线程数定义线程池允许创建的最大线程数量包括核心线程和非核心线程。long keepAliveTime, // 空闲线程存活时间定义当线程池中的线程数量超过corePoolSize 时多余的空闲线程在终止前等待新任务的最长时间。TimeUnit unit, // 时间单位BlockingQueueRunnable workQueue, // 任务队列定义用于保存等待执行的任务的阻塞队列。任务缓冲区核心作用是在线程资源有限时暂存待执行任务平衡任务提交速度与线程处理能力。SynchronousQueue同步移交队列LinkedBlockingQueue无界/有界队列ArrayBlockingQueue有界队列PriorityBlockingQueue优先级队列DelayQueue延迟队列ThreadFactory threadFactory, // 线程工厂用于创建新线程的工厂类。RejectedExecutionHandler handler // 拒绝策略定义当线程池和队列都满了无法处理新任务时的处理策略。内置拒绝策略AbortPolicy默认抛出RejectedExecutionExceptionCallerRunsPolicy调用者线程执行 - 可能会在主线程中执行耗时任务可能会奔溃DiscardPolicy静默丢弃DiscardOldestPolicy丢弃队列中最旧的任务线程数变化示意图任务提交 → 当前线程数 corePoolSize → 创建新线程任务提交 → 当前线程数 corePoolSize → 任务入队任务提交 → 队列已满 当前线程数 maximumPoolSize → 创建新线程任务提交 → 队列已满 当前线程数 maximumPoolSize → 执行拒绝策略这个例子创建多个线程池如果第1个满了使用第2个如果又满了就使用新的线程执行。/** * Author : wn * Email : maoning20080809163.com * Date : 2025/12/21 12:28 * Description : 测试线程池 */ public classThreadPoolMainActivityextends AppCompatActivity implements View.OnClickListener{ Override protected void onCreate(Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.thread_pool_main); findViewById(R.id.thread_pool_btn1).setOnClickListener(this); findViewById(R.id.thread_pool_btn2).setOnClickListener(this); findViewById(R.id.thread_pool_btn3).setOnClickListener(this); findViewById(R.id.thread_pool_btn4).setOnClickListener(this); } Override public void onClick(View v) { if(v.getId() R.id.thread_pool_btn1){ ThreadPoolExecutorHelper.test1(); } else if(v.getId() R.id.thread_pool_btn2){ ThreadPoolExecutorHelper.test2(); } else if(v.getId() R.id.thread_pool_btn3){ThreadPoolExecutorAutoHelper.test3();} else if(v.getId() R.id.thread_pool_btn4){ThreadPoolExecutorAutoHelper.test4();} } }/** * Author : wn * Email : maoning20080809163.com * Date : 2025/12/21 17:10 * Description : */ public classThreadPoolExecutorAutoHelper{ //线程池自动切换 线程最大数(核心非核心线程)等待队列都用完才异常。 public static void test3(){ ThreadPoolExecutor cpuExecutor ThreadPoolExecutorAuto.getCpuExecutor(); //ThreadPoolMonitor threadPoolMonitor new ThreadPoolMonitor(cpuExecutor); for(int i 0; i 50; i){ ThreadTask3 threadTask3 new ThreadTask3(ThreadTask3 i i); try { cpuExecutor.execute(threadTask3); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorHelper test3() i i); } catch (RejectedExecutionException e){ try { //cpu线程池异常 , 使用io线程池 线程最大数等待队列 LogUtils.Companion.w(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorAutoHelper test3() cpu RejectedExecutionException e e.getMessage()); ThreadPoolExecutor ioExecutor ThreadPoolExecutorAuto.getIoExecutor(); ioExecutor.execute(threadTask3); } catch (RejectedExecutionException e1){ //io线程池也异常 LogUtils.Companion.e(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorAutoHelper test3() io RejectedExecutionException e e.getMessage()); //使用新的Thread执行或者想想其他的扩展实现 一定要使用start() new Thread(threadTask3, cpu-io all exception).start(); } } } } //先调用test3测试线程池满了以后使用子线程。再用比较少的线程看看线程池能否正常执行 public static void test4(){ ThreadPoolExecutor cpuExecutor ThreadPoolExecutorAuto.getCpuExecutor(); //ThreadPoolMonitor threadPoolMonitor new ThreadPoolMonitor(cpuExecutor); for(int i 0; i 3; i){ ThreadTask3 threadTask3 new ThreadTask3(ThreadTask3 i i); try { cpuExecutor.execute(threadTask3); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorHelper test4() i i); } catch (RejectedExecutionException e){ try { //cpu线程池异常 , 使用io线程池 线程最大数等待队列 LogUtils.Companion.w(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorAutoHelper test4() cpu RejectedExecutionException e e.getMessage()); ThreadPoolExecutor ioExecutor ThreadPoolExecutorAuto.getIoExecutor(); ioExecutor.execute(threadTask3); } catch (RejectedExecutionException e1){ //io线程池也异常 LogUtils.Companion.e(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorAutoHelper test4() io RejectedExecutionException e e.getMessage()); //使用新的Thread执行或者想想其他的扩展实现 一定要使用start() new Thread(threadTask3, cpu-io all exception).start(); } } } } }/** * Author : wn * Email : maoning20080809163.com * Date : 2025/12/21 15:17 * Description : 多线程池自动切换如果cpu线程池满了自动切换到io线程池 */ public classThreadPoolExecutorAuto{//CPU密集型线程池 private static ThreadPoolExecutor cpuExecutor; //IO密集型任务池 private static ThreadPoolExecutor ioExecutor;//单线程顺序执行池 private static ThreadPoolExecutor serialExecutor; static { //线程数 int cpuCount Runtime.getRuntime().availableProcessors(); //int cpuCount 2; LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, ThreadPoolExecutorManager cpuCount cpuCount); //CPU密集型处理图像计算等 cpuExecutor new ThreadPoolExecutor( cpuCount, cpuCount 1, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue(10), //队列也不能太多会导致等待时间太久。 new CustomThreadFactory(ThreadPoolExecutorAuto my-cpu-pool, Thread.MAX_PRIORITY - 1), new ThreadPoolExecutor.AbortPolicy() //抛出异常策略 ); //IO密集型网络请求、文件读写 ioExecutor new ThreadPoolExecutor( cpuCount * 2, cpuCount * 3, 6L, TimeUnit.SECONDS, new LinkedBlockingQueue(20), new CustomThreadFactory(ThreadPoolExecutorAuto my-io-pool, Thread.NORM_PRIORITY), new ThreadPoolExecutor.AbortPolicy() //抛出异常测试了 ); //串行执行数据库操作等需要顺序执行的任务 serialExecutor new ThreadPoolExecutor( 1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue(), new CustomThreadFactory(ThreadPoolExecutorAuto my-serial-pool, Thread.NORM_PRIORITY) ); //防止内存泄漏监听应用生命周期 Application application MyApp.myApp; application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { Override public void onActivityCreated(NonNull Activity activity, Nullable Bundle savedInstanceState) { } Override public void onActivityStarted(NonNull Activity activity) { } Override public void onActivityResumed(NonNull Activity activity) { } Override public void onActivityPaused(NonNull Activity activity) { } Override public void onActivityStopped(NonNull Activity activity) { } Override public void onActivitySaveInstanceState(NonNull Activity activity, NonNull Bundle outState) { } Override public void onActivityDestroyed(NonNull Activity activity) { //清理与Activity相关的任务 LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, 清理与Activity相关的任务 ThreadPoolExecutorManager onActivityDestroyed activity); } }); } //CPU密集型线程池 public static ThreadPoolExecutor getCpuExecutor(){ return cpuExecutor; } //IO密集型任务池 public static ThreadPoolExecutor getIoExecutor(){ return ioExecutor; } //单线程顺序执行池 public static ThreadPoolExecutor getSerialExecutor(){ return serialExecutor; } }/** * Author : wn * Email : maoning20080809163.com * Date : 2025/12/21 15:50 * Description : */ public classThreadTask3implements Runnable{ //private static final String TAG ThreadTask2; private String threadTaskName; public ThreadTask3(String name){ this.threadTaskName name; } private static int taskCount 1; Override public void run() { try { Thread.sleep(100); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, ThreadTask3 执行任务taskCount taskCount isMain isMainThread() , threadTaskName , Thread.currentThread().getName() , Thread.currentThread().getId() , this.getClass()); taskCount ; //这里执行的是子线程 如果使用handler刷新必须指定在主线程中执行Looper.getMainLooper() /*new Handler(Looper.getMainLooper()).post(() - { //LogUtils.Companion.i(TAG, ThreadTask2 执行任务 Thread.currentThread().getName() , Thread.currentThread().getId()); });*/ } catch (Exception e){ e.printStackTrace(); } } public boolean isMainThread() { // 方法1比较当前线程和主线程的线程对象 return Looper.myLooper() Looper.getMainLooper(); //return Looper.getMainLooper().getThread() Thread.currentThread(); } }/** * Author : wn * Email : maoning20080809163.com * Date : 2025/12/21 15:37 * Description : 线程池监控 */ public classThreadPoolMonitor{ private ThreadPoolExecutor executor; private ScheduledExecutorService monitor; public ThreadPoolMonitor(ThreadPoolExecutor executor){ this.executor executor; //启动监控 monitor Executors.newSingleThreadScheduledExecutor(); monitor.scheduleAtFixedRate(this::reportStatus, 0, 5, TimeUnit.SECONDS); } private void reportStatus(){ LogUtils.Companion.d(ThreadPoolExecutorHelper.TAG, ThreadPoolMonitor reportStatus());StringBuilder sb new StringBuilder(); sb.append(ThreadPoolMonitor reportStatus() ); sb.append( , Pool Size : executor.getPoolSize()); sb.append( , Max Pool Size : executor.getMaximumPoolSize()); sb.append( , Core Pool Size : executor.getCorePoolSize()); sb.append( , Active Threads : executor.getActiveCount()); sb.append( , Queue Size : executor.getQueue().size()); sb.append( , Completed Tasks : executor.getCompletedTaskCount()); sb.append( , Largest Pool Size : executor.getLargestPoolSize()); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, sb.toString());//动态调整如果队列长期满载增加核心线程数 - 可以灵活配置 if(executor.getQueue().size() 80){ executor.setCorePoolSize(Math.min(executor.getCorePoolSize() 2, executor.getMaximumPoolSize())); } } public void shutdown(){ executor.shutdown(); monitor.shutdown(); } }thread_pool_main.xml布局?xml version1.0 encodingutf-8? androidx.constraintlayout.widget.ConstraintLayout android:layout_widthmatch_parent android:layout_heightmatch_parent xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:apphttp://schemas.android.com/apk/res-auto xmlns:toolshttp://schemas.android.com/tools androidx.appcompat.widget.AppCompatTextView android:idid/thread_pool_title android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintTop_toTopOfparent app:layout_constraintStart_toStartOfparent app:layout_constraintEnd_toEndOfparent android:layout_marginTop20dp android:textSize30sp android:textColorcolor/black android:text测试线程池/ androidx.appcompat.widget.AppCompatButton android:idid/thread_pool_btn1 android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintStart_toStartOfparent app:layout_constraintTop_toBottomOfid/thread_pool_title android:text测试线程池满抛出异常/ androidx.appcompat.widget.AppCompatButton android:idid/thread_pool_btn2 android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintStart_toStartOfparent app:layout_constraintTop_toBottomOfid/thread_pool_btn1 android:textColorcolor/red android:text测试线程池状态/ androidx.appcompat.widget.AppCompatButton android:idid/thread_pool_btn3 android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintStart_toStartOfparent app:layout_constraintTop_toBottomOfid/thread_pool_btn2 android:textColorcolor/blue android:text测试线程池自动切换设计 - 非常多线程同时执行/ androidx.appcompat.widget.AppCompatButton android:idid/thread_pool_btn4 android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintStart_toStartOfparent app:layout_constraintTop_toBottomOfid/thread_pool_btn3 android:textColorcolor/blue android:text测试线程池自动切换设计 - 少量线程执行/ /androidx.constraintlayout.widget.ConstraintLayout
延伸阅读

更多相关文章

2026/11/2 4:59:50

Claude Code用量限制解析:20x usage仅作用于5小时窗口

1. 从一条限制提示说起:20x usage、5小时窗口与每周限制最近不少使用 Claude Code 的开发者都遇到了类似的提示,其中一条比较有代表性:Your limits are temporarily boosted. Your weekly Claude Code limit is 50% higher.还有同学在社区里讨…

2026/11/3 14:08:59

313MB加密包背后的静默上传暗门:Android恶意样本分析实战

在移动安全测试这一行待久了,各种奇怪的样本你都会遇到。前阵子我手头就多了一个313MB的加密包——名字看着是个通用工具类Android应用,体积却大得离谱,而且整体被加固加密处理过,静态扫描基本扫不出东西。这种组合在真实黑产样本…

2026/11/3 14:08:59

深度学习张量类型转换:从原理到实战的避坑指南

1. 张量类型转换到底在转什么 刚接触深度学习框架那会儿,我对张量的类型转换完全没概念,觉得不就是 float 转 int 嘛,能有什么坑。结果第一次跑模型就报了个错,说期望的输入类型是 Float ,实际拿到的是 Double …

2026/11/3 14:08:59

汉语在科技领域的独特优势与应用前景

1. 汉语在科技时代的独特优势 汉语作为世界上使用人数最多的语言之一,正在科技领域展现出惊人的潜力。与拼音文字不同,汉语的象形文字特性使其在信息密度和表达效率上具有天然优势。一个汉字往往能表达一个完整的概念,而英语可能需要多个单词…

2026/11/3 14:08:59

热电比0.5-1.2调节技术与能源系统优化实践

1. 热电比波动范围解析:0.5-1.2的技术内涵与应用价值 热电比(Thermal-to-Electric Ratio)是能源系统中衡量热能输出与电能输出比例的关键参数。当这个比值在0.5到1.2之间波动时,意味着系统可以根据需求灵活调整热能和电能的产出比…

2026/11/3 14:08:59

区块链如何重塑海外红人营销生态

1. 海外红人营销的现状与挑战 海外红人营销在过去十年经历了爆炸式增长,但传统的中心化模式正面临多重挑战。品牌方通常需要通过MCN机构或第三方平台联系红人,这种模式存在几个显著痛点: 首先,中间环节的抽成高达30-50%。某美妆品…

2026/11/3 14:03:59

OpenClaw多Agent架构:构建自动化AI虚拟公司实践

1. 项目概述:用OpenClaw构建AI虚拟公司去年底我在测试OpenClaw多Agent功能时突发奇想:能不能用这个框架模拟一家完整的科技公司?经过两个月的调教,现在我的"AI公司"已经能自动处理产品需求、编写代码、测试部署&#xf…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑