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开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO