Android 中线程池的理解

2024-08-22 15:08
文章标签 android 理解 中线 程池

本文主要是介绍Android 中线程池的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android 中线程池的理解

前言

Android的日常开发中会用到线程池的地方也不少见,Android中的线程池也是沿用了Java的Executor的方式。关于这些资料网上能搜罗出一大把。现在突然看了一下源码,感觉灵光一闪呀。在这里把自己的理解记录下来。

以前来说,对于线程池的使用只知道有4中,分别为:FixedThreadPoolCachedThreadPoolScheduledThreadPoolSingleThreadExecutor,然而不知道其中的原理。后来翻了一下源码,发现这4中线程池的具体实现都是通过一个方法来实现的:

/*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters and default thread factory and rejected execution handler.* It may be more convenient to use one of the {@link Executors} factory* methods instead of this general purpose constructor.** @param corePoolSize the number of threads to keep in the pool, even*        if they are idle, unless {@code allowCoreThreadTimeOut} is set* @param maximumPoolSize the maximum number of threads to allow in the*        pool* @param keepAliveTime when the number of threads is greater than*        the core, this is the maximum time that excess idle threads*        will wait for new tasks before terminating.* @param unit the time unit for the {@code keepAliveTime} argument* @param workQueue the queue to use for holding tasks before they are*        executed.  This queue will hold only the {@code Runnable}*        tasks submitted by the {@code execute} method.* @throws IllegalArgumentException if one of the following holds:<br>*         {@code corePoolSize < 0}<br>*         {@code keepAliveTime < 0}<br>*         {@code maximumPoolSize <= 0}<br>*         {@code maximumPoolSize < corePoolSize}* @throws NullPointerException if {@code workQueue} is null*/
public ThreadPoolExecutor(int corePoolSize,int maximunPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory)
  • corePoolSize:根据上面注释的解释,这个参数代表核心线程数,这些线程是在线程池保存,即使在闲置的状态下也不会销毁的。除非调用了allowCoreThreadTimeOut(true)方法。

  • maximunPoolSize:这个参数代表的是线程池中最大的线程数,包括和核心线程和普通线程。当活动线程数量达到这个数值后,后续任务会被阻塞

  • keepAliveTime:普通线程在限制状态下的超时时间,超过这个时间之后,线程就会被终止。当allowCoreThreadTimeOut(true)被调用后,这个参数对核心线程也生效

  • unit:这个参数代表keepAliveTime的单位,通常有TimeUnit.MILLSECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分钟)等。

  • workQueue:用来保存那些还没有执行的Runnable对象的队列,只有使用execute方法的对象才会保存在这个队列中。当线程池中的线程数量大于核心线程数的时候,会把线程保存在这里。如果线程池的线程数量没有达到最大值,就开启新的普通线程来执行这些任务。如果这个队列保存的任务数达到了上限,而且没有空闲线程的话,则拒绝执行任务。

  • threadFactory:线程工厂,为线程池提供创建新的线程功能。

JAVA中为我们提供了几个具体的线程池实现类:

FixedThreadPool

通过Executors.newFixedThreadPool()来创建

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

}

FixedThreadPool的实现得知,该线程池具有固定的线程数量,当线程处于空闲状态下,都不会被回收,除非线程池关闭了,当线程池的所有线程都在活动状态的时候,新任务会保存在队列中,并且new LinkedBlockingQueue<Runnable>()这个队列是没有大小限制的。由于线程不会被回收,所以这种线程池能够快速的响应任务。

CachedThreadPool

通过Executors.newCachedThreadPool()创建。

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

可以看到,这个线程池没有核心线程,但是线程数量最大值为Integer.MAX_VALUE,这意味着能线程池的线程数量差不多可以无限大,当一个新任务来到的时候,就检验是否有闲置的线程,如果有就直接执行,没有就创建一个来执行。闲置线程的超时时间为60秒。超过60秒之后就会被回收。

关于SynchronousQueue上网查询了一下资料,这个对象是一个只有一个元素的队列,只有队列当请求取出的时候才能插入,内部并没有数据缓存空间。我们可以简单理解为这个其实没什么乱用的东西,在这里的场景中只是实现了任务能被马上执行。

通过以上特点,我觉得这个线程池适合用于大量耗时短的任务,并且因为当没有任务的时候,线程池是空的,所以系统资源占用比较少。

ScheduledThreadPool

通过Executors.newScheduledThreadPool()创建

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);
}public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE,DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,new DelayedWorkQueue());
}

其中 DEFAULT_KEEPALIVE_MILLIS 的值为10L,意味着10毫秒就会回收闲置线程,这个线程池的最大线程数量也没有限制,主要的适用场景可能为定时任务或者固定周期性任务。

SingleThreadExecutor

通过Executors.newSingleThreadExecutor方法来创建。

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

这个线程池的内部只有一个核心线程,所有的任务都在同一个线程按顺序执行,这些线程就不需要处理线程之间同步的问题了,看具体的适用场景了。

这篇关于Android 中线程池的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1096621

相关文章

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE