Android线程池(转)
.前言
转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337
使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用,减少创建和销毁线程的性能开销。其次,能控制线程池中的并发数,否则会因为大量的线程争夺CPU资源造成阻塞。最后,线程池能够对线程进行管理,比如使用ScheduledThreadPool来设置延迟N秒后执行任务,并且每隔M秒循环执行一次。
下面会通过介绍线程池中的真正实现者——类线程池的使用以及特性分析,会加上笔者自己的理解,和自认为比较恰当的比喻,帮助理解。
.凡事得靠ThreadPoolExecutor(铺垫环节,懂的直接跳过)
Executor作为一个接口,它的具体实现就是ThreadPoolExecutor。
Android中的线程池都是直接或间接通过配置ThreadPoolExecutor来实现不同特性的线程池。
先介绍ThreadPoolExecutor的一个常用的构造方法。
- /*
- *@ ThreadPoolExecutor构造参数介绍
- *@author SEU_Calvin
- * @date 2016/09/03
- */
- public ThreadPoolExecutor(
- //核心线程数,除非allowCoreThreadTimeOut被设置为true,否则它闲着也不会死
- int corePoolSize,
- //最大线程数,活动线程数量超过它,后续任务就会排队
- int maximumPoolSize,
- //超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收
- long keepAliveTime,
- //枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等
- TimeUnit unit,
- //缓冲任务队列,线程池的execute方法会将Runnable对象存储起来
- BlockingQueue<Runnable> workQueue,
- //线程工厂接口,只有一个new Thread(Runnable r)方法,可为线程池创建新线程
- ThreadFactory threadFactory)
ThreadPoolExecutor的各个参数所代表的特性注释中已经写的很清楚了,那么ThreadPoolExecutor执行任务时的心路历程是什么样的呢?(以下用currentSize表示线程池中当前线程数量)
(1)当currentSize<corePoolSize时,没什么好说的,直接启动一个核心线程并执行任务。
(2)当currentSize>=corePoolSize、并且workQueue未满时,添加进来的任务会被安排到workQueue中等待执行。
(3)当workQueue已满,但是currentSize<maximumPoolSize时,会立即开启一个非核心线程来执行任务。
(4)当currentSize>=corePoolSize、workQueue已满、并且currentSize>maximumPoolSize时,调用handler默认抛出RejectExecutionExpection异常。
. Android中的四类线程池
Android中最常见的四类具有不同特性的线程池分别为FixThreadPool、CachedThreadPool、ScheduleThreadPool以及SingleThreadExecutor。
2.1 FixThreadPool(一堆人排队上公厕)
- /*
- *@FixThreadPool介绍
- *@author SEU_Calvin
- * @date 2016/09/03
- */
- public static ExecutorService newFixThreadPool(int nThreads){
- return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
- }
- //使用
- Executors.newFixThreadPool(5).execute(r);
(1)从配置参数来看,FixThreadPool只有核心线程,并且数量固定的,也不会被回收,所有线程都活动时,因为队列没有限制大小,新任务会等待执行。
(2)【前方高能,笔者脑洞】FixThreadPool其实就像一堆人排队上公厕一样,可以无数多人排队,但是厕所位置就那么多,而且没人上时,厕所也不会被拆迁,哈哈o(∩_∩)o ,很形象吧。
(3)由于线程不会回收,FixThreadPool会更快地响应外界请求,这也很容易理解,就好像有人突然想上厕所,公厕不是现用现建的。
2.2 SingleThreadPool(公厕里只有一个坑位)
- /*
- *@SingleThreadPool介绍
- *@author SEU_Calvin
- * @date 2016/09/03
- */
- public static ExecutorService newSingleThreadPool (int nThreads){
- return new FinalizableDelegatedExecutorService ( new ThreadPoolExecutor (1, 1, 0, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()) );
- }
- //使用
- Executors.newSingleThreadPool ().execute(r);
(1)从配置参数可以看出,SingleThreadPool只有一个核心线程,确保所有任务都在同一线程中按顺序完成。因此不需要处理线程同步的问题。
(2)【前方高能,笔者脑洞】可以把SingleThreadPool简单的理解为FixThreadPool的参数被手动设置为1的情况,即Executors.newFixThreadPool(1).execute(r)。所以SingleThreadPool可以理解为公厕里只有一个坑位,先来先上。为什么只有一个坑位呢,因为这个公厕是收费的,收费的大爷上年纪了,只能管理一个坑位,多了就管不过来了(线程同步问题)。
2.3 CachedThreadPool(一堆人去一家很大的咖啡馆喝咖啡)
- /*
- *@CachedThreadPool介绍
- *@author SEU_Calvin
- * @date 2016/09/03
- */
- public static ExecutorService newCachedThreadPool(int nThreads){
- return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit. SECONDS, new SynchronousQueue<Runnable>());
- }
- //使用
- Executors.newCachedThreadPool().execute(r);
(1)CachedThreadPool个线程的可能)处理任务。
(2)任务队列SynchronousQueue相当于一个空集合,导致任何任务都会被立即执行。
(3)【前方高能,笔者脑洞】CachedThreadPool就像是一堆人去一个很大的咖啡馆喝咖啡,里面服务员也很多,随时去,随时都可以喝到咖啡。但是为了响应国家的“光盘行动”,一个人喝剩下的咖啡会被保留60秒,供新来的客人使用,哈哈哈哈哈,好恶心啊。如果你运气好,没有剩下的咖啡,你会得到一杯新咖啡。但是以前客人剩下的咖啡超过60秒,就变质了,会被服务员回收掉。
(4)比较适合执行大量的耗时较少的任务。喝咖啡人挺多的,喝的时间也不长。
个里面唯一一个有延迟执行和周期重复执行的线程池)
- /*
- *@ScheduledThreadPool介绍
- *@author SEU_Calvin
- * @date 2016/09/03
- */
- public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){
- return new ScheduledThreadPoolExecutor(corePoolSize);
- }
- public ScheduledThreadPoolExecutor(int corePoolSize){
- super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedQueue ());
- }
- //使用,延迟1秒执行,每隔2秒执行一次Runnable r
- Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);
(1)核心线程数固定,非核心线程(闲着没活干会被立即回收)数没有限制。
(2)从上面代码也可以看出,ScheduledThreadPool主要用于执行定时任务以及有固定周期的重复任务。
至此Android中最常见的四类不同特性的线程池内容总结完毕。
转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337
Android线程池(转)的更多相关文章
- Android(java)学习笔记267:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- android线程池ThreadPoolExecutor的理解
android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...
- android 线程池的使用
转自http://www.trinea.cn/android/java-android-thread-pool/ Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的 ...
- Android(java)学习笔记211:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- Android 线程池概念及使用
一:使用线程池的原因 在android开发中经常会使用多线程异步来处理相关任务,而如果用传统的newThread来创建一个子线程进行处理,会造成一些严重的问题: 在任务众多的情况下,系统要为每一个任务 ...
- 最强大的Android线程池框架
背景 大家都知道在我们的开发中永远都离不开多线程,对于我们为什么要使用多线程,多线程的使用和多线程的一些基础知识这里我们就不讲了,有兴趣的朋友可以去看一下博主之前的几篇文章: 线程你真的了解它吗 这才 ...
- -Android -线程池 批量上传图片 -附php接收代码
(出处:http://www.cnblogs.com/linguanh/) 目录: 1,前序 2,类特点 3,用法 4,java代码 5,php代码 1,前序 还是源于重构,看着之前为赶时间写着的碎片 ...
- Java(Android)线程池
1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() ...
- Android线程池(二)
本篇主要介绍Android自带的线程池的管理. 包含开始任务.重新加载.添加删除任务等,示例代码如下: package com.jiao.threadpooltest; import java.uti ...
- Android线程池(一)
本篇文章主要介绍Android自带的线程池的使用. 首先要引入线程池的概念 线程池:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务. 线程池线程都是后台线程.每个线 ...
随机推荐
- c++之函数值传递和引用传递解析----关键在于理解函数return的实现机制(内存分配)
函数调用过程解析 func里的a存储在调用fun函数时开辟的栈空间里,这块栈只在调用func时对func可用,调用结束后返回的a,其实是暂存在寄存器里的(一般情况下是eax),而返回到main里时,m ...
- linux 中的局部变量、全局变量、shell 变量的总结
系统局部变量和全局变量 一.变量分类局部变量和环境变量,局部变量只适用于当前shell,而环境变量是全局的,它适用于所有当前shell以及其派生出来的任意子进程,有些变量是用户创建的,其他的则是专用 ...
- bzoj4833
$数论$ $这个题已经忘了怎么做了,也不想知道了,只记得看了3个小时$ $对于有gcd(f_i, f_j) = f_{gcd(i, j)}性质的数列,以下结论适用$ #include<bits/ ...
- 二、myeclipse中配置mybatis中xml的自动提示
以mybatis中mapper.xml为例 方法一: 步骤一:在mybatis-3.3.0.jar包中寻找mybatis-3-mapper.dtd文件. 可以用360压缩打开mybatis-3.3.0 ...
- TimeUtils(没试过)
package util; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.ParseExc ...
- Flutter实战视频-移动电商-14.首页_url_launcher一键拨打店长电话
14.首页_url_launcher一键拨打店长电话 首页拨打电话的功能. 接收连个值,一个是店长的头像,一个是电话号码, 然后开始写我们的build方法.点击图片的时候要有一个拨打电话的动作.我们要 ...
- 如何将linux主机接入到网络中
前言: 这篇博客的主旨就想文章题目说的那样,当我们拿到一台新的系统时,我们怎么实现让你的主机连接到网络中.配置网络就是给你的系统配置IP地址,子网掩码,网关以及DNS.也就是说配置好这几项计算机上网的 ...
- CCF 201512-4 送货 (并查集+DFS,欧拉路)
问题描述 为了增加公司收入,F公司新开设了物流业务.由于F公司在业界的良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了城市的每条街道.然而,F公司现在只安排了小明一个人负责所有街道的服 ...
- React 从入门到进阶之路(七)
之前的文章我们介绍了 React 表单详解 约束性和非约束性组件 input text checkbox radio select textarea 以及获取表单的内容.接下来我们将介绍 Rea ...
- React 从入门到进阶之路(六)
之前的文章我们介绍了 React 表单事件 键盘事件 事件对象以及 React中 的 ref 获取 dom 节点 .双向数据绑定.接下来我们将介绍 React 表单详解 约束性和非约束性组件 inpu ...