Android线程池解析

android线程池深度解析 最近撸了ThreadPoolExecutor.java源码,对java线程池的理解帮助很大,和大家分享下。 阅读详情

因为有了线程池的存在,我现在都很少通过new Thread创建线程执行任务,一般都是直接new Runnable直接扔进线程池去执行,除非我对Thread有十足的把握能控制住(执行、中断、销毁)。

线程池的好处

(1)重用存在的线程,减少对象创建、消亡的开销,性能佳。这个池机制的好处。
(2)可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
(3)提供定时执行、定期执行、单线程、并发数控制等功能。

线程池概述

Android的线程池都是通过配置ThreadPoolExecutor来实现的,来,我们看看ThreadPoolExecutor的构造函数:

 public ThreadPoolExecutor(int corePoolSize,  
                           int maximumPoolSize,  
                           long keepAliveTime,  
                           TimeUnit unit,  
                           BlockingQueue<Runnable> workQueue,  
                           ThreadFactory threadFactory) {  
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,  
         threadFactory, defaultHandler);  
}  

我们分析一下每个参数的作用:
corePoolSize: 线程池的核心线程数。默认情况,核心线程会一直在线程池中存在,即使处于闲置的状态。除非设置ThreadPoolExecutor的allowCoreThreadTimeOut属性为true,此时,闲置的核心线程如果在keepAliveTime时间内没有新的任务要执行,就会被销毁。

maximumPoolSize:线程池最大线程数。如果线程池达到最大线程数,如果有新的任务进来,可能会加入队列,如果队列也满了,可能会阻塞或者直接拒绝。

keepAliveTime: 非核心线程闲置时的等待时间。如果非核心线程闲置了,在keepAliveTime时间内,没有新的任务到来,那么这个非核心就会被销毁。如果设置ThreadPoolExecutor的allowCoreThreadTimeOut属性为true,同样对核心线程生效。

unit: keepAliveTime的时间单位,有以下几种:
TimeUnit.MILLISECONDS; // 毫秒
TimeUnit.SECONDS; // 秒
TimeUnit.MINUTES; // 分钟
TimeUnit.HOURS; //小时
TimeUnit.DAYS; //天

workQueue: 线程池的任务队列,通过ThreadPoolExecutor的execute方法提交的Runnable任务都会储存在这个队列里面,等待执行。

threadFactory: 线程工厂,主要提供创建新的线程的功能。ThreadFactory是一个接口,只有一个方法:Thread newThread(Runnable r)。

还有一个不常用的参数,RejectedExecutionHandler handler。这个参数的作用当线程池无法在继续执行新任务时,这可能是任务队列满了或者是无法成功执行任务,此时会调用RejectedExecutionHandler的rejectedExecutoion()来通知调用者拒绝任务。知道就好。

再来说说线程池执行任务的规则/流程(重点):
(1)当通过ThreadPoolExecutor的execute方法提交的Runnable任务时,先会判断线程池中的线程是否超过核心线程数量corePoolSize。如果没有超过,则新建一个核心线程执行Runnable任务。如果超过,转到(2)。
(2)如果线程池的线程超过核心线程数corePoolSize,先来的Runnable任务会加入workQueue队列中,如果队列也已经满了,转到(3)。
(3)如果队列也满了,如果此时线程池的线程数量没有达到最大线程数量maximumPoolSize,那么启动一个非核心线程执行队列任务。如果超过了,转到(4)。
(4)队列也满了,线程池的线程数也达到了最大线程数量maximumPoolSize,此时就会调用RejectedExecutionHandler的rejectedExecutoion()来通知调用者拒绝任务。
线程池执行任务的规则/流程

其实Android已经为我们提供4种线程池使用:
(1)FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {  
    return new ThreadPoolExecutor(nThreads, nThreads,  
                                  0L, TimeUnit.MILLISECONDS,  
                                  new LinkedBlockingQueue<Runnable>());  
}

这是一种固定数量为nThreads的线程池,没有非核心线程,无限队列,所以不会拒绝新的任务,如果有闲置的线程,则执行任务,没有,新的任务会被加入队列中,等待被执行。

(2)CachedThreadPool

public static ExecutorService newCachedThreadPool() {  
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
                                  60L, TimeUnit.SECONDS,  
                                  new SynchronousQueue<Runnable>());  
}

没有核心进程,全部任务都会加入SynchronousQueue队列中,因为最大线程数为Integer.MAX_VALUE,说明非核心线程可以很多,所以一旦新的任务加入SynchronousQueue队列,就会创建新的非核心线程去执行,所以可以执行“无限”个任务。非核心线程的闲置时间的60秒,一旦超过60秒没有执行新的任务,就会被销毁。
再解析一下SynchronousQueue (同步队列)。这种队列内部不会存储元素, 每一次插入操作都会先进入阻塞状态,一直等到另一个线程执行了删除操作,然后该插入操作才会执行。同样地,每一次删除操作也都会先进入阻塞状态,一直等到另一个线程执行了插入操作,然后该删除操作才会执行。 当提交一个任务到包含这种 SynchronousQueue 队列的线程池以后,线程池会去检测是否有可用的空闲线程来执行该任务,如果没有就直接新建一个线程来执行该任务而不是将该任务先暂存在队列中。

(3)ScheduledThreadPool

public ScheduledExecutorService newScheduledThreadService(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {  
    super(corePoolSize, Integer.MAX_VALUE,  
          0, NANOSECONDS,  
          new DelayedWorkQueue());  
}

有核心线程数,最大线程数为Integer.MAX_VALUE。一旦非核心线程闲置,立刻被销毁。可以执行定时任务和具有固定周期的重复任务。

(4)SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {  
    return new FinalizableDelegatedExecutorService  
        (new ThreadPoolExecutor(1, 1,  
                                0L, TimeUnit.MILLISECONDS,  
                                new LinkedBlockingQueue<Runnable>()));  
}

核心线程数和最大线程数为1,保证只有一个线程执行任务,确保所有的任务都按顺序执行。任务队列没有限制,可以执行任意多个任务。

线程池源码解析

请参考Java 线程池 ThreadPoolExecutor 源码分析

Android线程池全面解析:Executors工厂方法与阿里规约的深层思考 文章摘要: Android开发中合理使用线程池对应用性能至关重要。Executors提供的四种线程池(FixedThreadPool、CachedThreadPool、SingleThreadExecutor和ScheduledThreadPool)各有特点,但都暗藏风险:无界队列可能导致OOM,无限创建线程会耗尽资源。阿里Java规约建议手动创建线程池,通过控制核心参数(线程数、队列容量、拒绝策略)规避风险。最佳实践包括:使用有界队列、限制最大线程数、自定义线程工厂、选择合适的拒绝策略(如CallerRu 阅读详情

相关推荐

安卓面经_安卓基础面全解析(16/30)之线程池全解析

安卓开发时很多时候会用到多线程技术,多线程的知识点本系列已经讲过AsyncTask、HandlerThread等,最后我们来看看线程池

a763450633的博客 863

Android线程池的解析

线程池可以看作是存放和管理多个线程的池子。在多任务情况下,多个线程的频繁创建和销毁会占用大量的资源,并影响性能。而线程池通过复用线程,避免了这种频繁的创建和销毁操作,从而提高了资源使用效率。线程池的优势包括:1.对线程进行统一管理,避免资源浪费。2.复用线程,减少线程的创建和销毁开销。3.有效控制线程池的最大并发数,避免线程之间因相互抢占系统资源而导致的阻塞现象。

weixin_39788742的博客 1534

Android多线程和线程池的核心知识全面解析

本文对Android多线程和线程池的核心知识进行了详细解析。多线程可以帮助我们实现并发执行任务,提高应用程序的性能和响应能力。线程池则是管理和复用线程的技术,可以有效地控制线程的数量和资源消耗。通过合理地使用多线程和线程池,我们可以提高应用的并发能力和用户体验。希望本文对您理解Android多线程和线程池有所帮助,祝您在Android开发中取得更好的成果!

JaDentenet的博客 190

【Android】线程池解析

线程池类型特点使用场景拥有固定数量的线程,线程数不变负载较重的服务器,需要限制线程数量的场景根据需要创建新线程,空闲线程会被回收执行很多短期异步任务的程序可以安排在给定延迟后运行命令或定期地执行需要任务在后台定期执行或重复执行的程序只有一个线程,所有任务按照提交顺序依次执行需要保证任务顺序执行的场景。

2401_87463988的博客 1026

逆向分析TikTok的Cronet网络库:定位libsscronet.so并Hook关键SSL函数

本文深入探讨了逆向分析TikTok的Cronet网络库的技术细节,重点介绍了如何定位libsscronet.so并Hook关键SSL函数。通过Java到Native的调用链路追踪、So库定位策略和SSL验证函数的动态Hook技巧,帮助开发者突破定制化网络库的协议加密防护,实现流量解密和协议分析。

weixin_27875131的博客 969

保姆级教程:在Ubuntu 22.04上从零安装SUMO并运行第一个交通仿真

本教程详细介绍了在Ubuntu 22.04系统上从零安装SUMO交通仿真软件并运行第一个仿真的完整流程。涵盖环境准备、PPA源安装、核心组件验证、首次仿真案例运行以及进阶配置技巧,特别针对netedit路网编辑器和地图格式转换等实用工具进行重点讲解,帮助用户快速掌握SUMO在交通仿真领域的应用。

weixin_30546189的博客 422

【Android】线程池的解析

线程池类型特点适用场景核心线程数最大线程数空闲线程存活时间拥有固定数量的线程,线程数不变。负载较重的服务器,需要限制线程数量的场景。固定固定无根据需要创建新线程,空闲线程会被回收。执行很多短期异步任务的程序。060秒可以安排在给定延迟后运行命令或定期地执行。需要任务在后台定期执行或重复执行的程序。固定固定60秒只有一个线程,所有任务按照提交顺序依次执行。需要保证任务顺序执行的场景。11无文章到这里就结束了!

2301_79828182的博客 1226

YOLOv8 TensorRT C++部署实战详解:从XMake构建到推理流水线

本项目实现了一个基于YOLOv8和TensorRT的高性能火灾烟雾检测系统,具有以下核心特点: 技术架构:采用TensorRT 8.6+进行GPU加速推理,结合CUDA 12.1和OpenCV 4.8+,实现高效计算机视觉处理。系统使用XMake替代CMake构建,配置更简洁高效。

hscing的博客 1065

全方位解析-Android中的线程池

笔记文章,没有废话,句句关键 线程池的优点 重用线程池里的线程,避免创建和销毁线程所带来的性能开销 有效控制最大并发数,避免造成线程间抢占系统资源而造成阻塞 提高线程可管理性,可以统一进行分配,调优和监控的能力 Android中的线程池 复用Java中的Executor接口,具体实现类为ThreadPoolExecutor,它有一下几个参数: 参数 说明 注释 corePoolSize 线程池中核心线程数量 一直存活,即使处于闲置状态 maximumPoolSize 最大能创建的.

gg199402的博客 4167

想发故障诊断论文?手把手教你用CWRU数据集复现第一个Baseline模型

本文提供了一份基于CWRU轴承数据集的故障诊断Baseline模型实战指南,手把手教你从数据准备到模型构建的全流程。通过详细的Python代码示例和学术级实验设计,帮助初学者快速复现第一个故障诊断模型,为发表高质量论文奠定基础。

weixin_28681255的博客 428

使用Termux在Android设备上编译运行SpecCPU2006

SPEC2006搭配Termux,竟然还能这么玩?!

菜菜的菜园子 2960

Android 线程池深度解析

默认线程池的线程名称为 “pool-1-thread-1”,不利于调试。// 自定义线程工厂(指定线程名称和优先级)@Override// 线程优先级(1-10,默认5)// 非守护线程(避免进程退出时任务被中断)// 使用自定义工厂创建线程池3, 5,new LinkedBlockingQueue<>(10), // 有界队列(容量10)new CustomThreadFactory("ImageLoader") // 线程名前缀:ImageLoader-1优势。

weixin_37794278的博客 965

基于51单片机扫地机器人(全套Proteus仿真+原理图+程序+说明书)

(内含源程序代码,原理图,仿真,讲解视频,元件清单等,【精品】值得推荐!!!扫地机器人是以单片机为主控制器。通过单片机控制小车行驶、除尘、蜂鸣。扫地机器人使用双电机驱动,以提高整车运动的平稳性;在智能车进驶过程中,采用双超声波模块实现避障。

2301_76434107的博客 1895

Android线程池源码解析

上一篇博客大概了解了下线程池是什么,这篇博客将在源码的基础上去验证上一篇博客中提到的 Thread执行流程。我的博客保证是一个字一个字敲出来的     1.线程池源码解析     在ThreadPoolExecutor类中,最核心的任务提交方法是execute()方法,所以就先从execte方法开始 来看看线程池的执行流程:     public void execute(R

刘建的博客 1046

保姆级教程:用VESTA软件5分钟搞定纳米颗粒Wulff Construction建模(以Au金为例)

本文提供了一份详细的VESTA软件教程,指导用户如何在5分钟内完成纳米颗粒Wulff Construction建模,特别以金(Au)为例。从环境搭建、基础晶体结构创建到Wulff Construction设置和可视化优化,涵盖了全流程操作步骤和常见问题解决方案,适合科研新手快速上手。

weixin_29311017的博客 436

VTK:vtkAssembly用法实战

VTK:vtkAssembly用法实战程序输出程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkAssembly.h> #include <vtkAxesActor.h> #include <vtkCubeSource.h> #include <vtkNamedColors.h> #include <vtkNew.h> #include <vtkOrientation

希望我的博客,能帮上你解决学习中工作中所遇到的问题 932

Android:线程池概念解析

主要内容 为什么要使用线程池 线程池的优点 线程池源码剖析 为什么要使用线程池 在 Android 中,我们使用子线程来处理异步任务。但是线程不可能无限制的产生,线程的创建和销毁会都会有相应的开销,如果在一段时间内频繁的创建和销毁线程,就会导致频繁的 GC,这样就会使程序的效率降低。 同时,线程之间由于没有统一的管理,就会争抢资源,容易造成卡顿,甚至应用崩溃。 这时候如果我们采用线程...

one1go的博客 797

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android 线程池源码解析

先从俩个概念说起在源码中我们常常能看到这么俩个变量:ctl,worker。ctlctl是什么呢? ctl在源码里的解释是: The main pool control state, ctl, is an atomic integer packing two conceptual fields 1.workerCount, indicating the effective number of t

allbule的博客 788

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android--线程池实现方式解析

使用场景:多线程一直是一个程序健壮性的基础条件,在实现复杂业务逻辑的时候往往需要使用多线程来完成业务逻辑操作。然而线程的创建与销毁是一个耗时操作,如果在程序中反复创建和销毁线程,将会对程序的反应速度造成严重影响,有时甚至会Crash掉程序。因此在需要平凡使用线程的业务场景中,使用线程池是一个不错的选择。 本文将为大家介绍Android线程池的实现方式。在Android中实现线程池,首先需要实现一

Inspiration 1万+

展开说说:Android线程池解析

何谓线程池?本人理解是存放和管理线程的一个容器。 线程池存在的意义是什么? 第一:前面博客提到过创建和销毁线程的操作本身是有性能开销的,如果把使用的线程对象存起来下次用的时候直接取出来用就省去了一次创建和销毁的成本,使用越频繁就越能节省性能,毕竟省到就是赚到嘛。 第二:方便的管理线程,避免很多线程同时争抢资源引发阻塞。毕竟是人家封装过的,因此有专门的属性参数来控制核心线程数、最大并发数、非核心线程的最大限制时长等。

Hidanchaofan的博客 1048

Android 线程池解析与复用原理

作为面试的常住嘉宾之一,线程池的拷问,估计每个面试官都想问一遍。 下面,我们一起来学习一下。 一、线程池 首先,提到线程池就得说说它的好处,总得来说,可以分为以下三点: 复用线程池的线程,避免线程创建和销毁带来的性能开销。 控制线程池的最大并发数,避免大量线程之间抢占系统资源而导致的阻塞现象 能够对线程进行简单的管理,并提供定时执行以及制定间隔循环执行等任务 但需要注意的一点,如果只有一个线程,且不需要复用,则不需要用到线程池,没必要。 我们都知道,Java的线程池共有4中,newFixedThread

夏至的稻穗的博客 1312

【Android 异步操作】线程池 ( 线程池 execute 方法源码解析 )

一、线程池 execute 方法源码解析、 二、线程池 execute 方法完整源码及注释

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1544

java android ExecutorService 线程池解析

ExecutorService: 它也是一个接口,它扩展自Executor接口,Executor接口更像一个抽象的命令模式,仅有一个方法:execute(runnable);Executor接口简单,但是很重要,重要在这种设计的模式上。。Java5以后,通过Executor来启动...

chouxie8829的博客 122

android 进程池 参数,Android 线程池全解析

什么是线程池我们都知道线程是什么,但是一提到线程池,给人的第一个感觉就是一堆线程,这样的理解其实不太对,线程池可以只有一个线程,也可以有多个线程,而线程池最大的作用是管理和复用线程。一提到管理线程,我们都知道线程池可以帮我们创建线程,也可以帮我们销毁线程。但是一提到复用线程,相信大多数人都愣了,要知道 Thread.start 执行完 Runnable.run 方法之后线程就自动停止了,也就是说 ...

weixin_35820423的博客 231

Android Binder线程池深度解析:为何跨进程数据传输受限?

本文深度解析了Android Binder线程池如何成为跨进程数据传输的关键瓶颈。核心在于所有Binder线程共享同一块1M-8K的用户态内存缓冲区,在多线程并发处理IPC请求时,单次事务能分配到的连续内存块远小于理论总值,这解释了为何大数据传输易触发TransactionTooLargeException。文章通过剖析线程池的创建、运作机制及共享内存模型,为开发者提供了规避数据传输限制的实战策略。

dog123的博客 625
上一篇: FutureTask源码浅析
下一篇: AsyncTask源码解析
JohanMan
博客等级 码龄10年 72粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值