发布时间:2026/9/3 9:07:45
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/9/3 9:07:45

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/9/3 9:32:49

从法国国庆日看技术协作:如何用文化日历提升全球团队效率

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

2026/9/3 9:32:49

手机投屏到电脑只需3步:QtScrcpy低延迟安卓投屏新手指南

手机投屏到电脑只需3步:QtScrcpy低延迟安卓投屏新手指南 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy QtScrcpy 是一款基于 Qt 框架的开源安卓投屏工具,通…

2026/9/3 9:32:48

360环视系统原理与C++实时实现关键技术解析

简介:本资源是一套面向自动驾驶算法工程师与计算机视觉开发者的技术实践Demo,聚焦360环视全景拼接这一ADAS核心功能,解决多摄像头图像校正、配准与无缝融合的工程落地难点。压缩包共24个文件(12.21MB),包含…

2026/9/3 9:32:48

ZYNQ软硬协同实战:FFT与打地鼠课设的AXI协议深度解析

简介:本资源为两套面向高校嵌入式系统与数字电路课程设计的ZYNQ实践项目,适用于具备FPGA基础和C语言能力的本科生及进阶学习者,旨在解决ZYNQ软硬协同开发中典型应用场景的工程实现问题。压缩包共含多个工程文件,主体为Vivado工程&…

2026/9/3 9:27:48

洗衣店小程序V2.4.3深度解析:业务规则驱动的数字化底座

简介:这是一套面向中小型洗衣店经营者与微信小程序开发者的数字化运营解决方案,聚焦于提升门店预约管理、会员服务与订单协同效率。资源包含V2.4.3版本的完整可部署包,涵盖小程序前端源码(WXML/WXSS/JS结构)、后端安装…

2026/9/1 16:02:17

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/2 9:00:32

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/2 8:41:06

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/3 0:02:06

零基础装 OpenClaw 小龙虾 AI:Windows 一键部署教程与避坑要点

Windows 部署 OpenClaw 完整教程|本地 AI 智能体 5 分钟落地,环境配置一次搞定 版本说明:Windows 3.1.0 / Mac 2.7.9 写在前面 近两年开源 AI 领域有一款被称作「数字员工」的工具持续走热,它就是 OpenClaw,圈内人更习…

2026/9/3 0:02:06

Hermes Agent 本地部署新方案:Windows 整合包减少依赖报错

Windows 本地部署 Hermes 太麻烦?这版一键包 5 分钟快速跑通 很多人想体验 Hermes Agent,但真正开始部署时,往往会卡在环境配置这一步。 需要安装各类依赖、调试运行环境、处理路径问题,还容易遇到命令行报错、系统拦截、文件缺…

2026/9/3 0:02:06

实测 OpenClaw 一键包,5 分钟完成本地自动化环境搭建

OpenClaw 本地 AI 自动化工具部署指南|使用一键包规避环境配置难题 痛点:部署 AI 自动化工具常常要处理 Python、Node.js 各类依赖,版本冲突、环境配置耗费大量时间,OpenClaw 提供一键安装包,降低部署门槛。 适配系统&…

2026/9/2 1:15:22

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/2 1:15:22

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/2 1:15:20

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…