.前言

转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337

使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用,减少创建和销毁线程的性能开销。其次,能控制线程池中的并发数,否则会因为大量的线程争夺CPU资源造成阻塞。最后,线程池能够对线程进行管理,比如使用ScheduledThreadPool来设置延迟N秒后执行任务,并且每隔M秒循环执行一次。

下面会通过介绍线程池中的真正实现者——类线程池的使用以及特性分析,会加上笔者自己的理解,和自认为比较恰当的比喻,帮助理解。

.凡事得靠ThreadPoolExecutor(铺垫环节,懂的直接跳过)

Executor作为一个接口,它的具体实现就是ThreadPoolExecutor。

Android中的线程池都是直接或间接通过配置ThreadPoolExecutor来实现不同特性的线程池。

先介绍ThreadPoolExecutor的一个常用的构造方法。

[java] view plain copy

 
  1. /*
  2. *@ ThreadPoolExecutor构造参数介绍
  3. *@author SEU_Calvin
  4. * @date 2016/09/03
  5. */
  6. public ThreadPoolExecutor(
  7. //核心线程数,除非allowCoreThreadTimeOut被设置为true,否则它闲着也不会死
  8. int corePoolSize,
  9. //最大线程数,活动线程数量超过它,后续任务就会排队
  10. int maximumPoolSize,
  11. //超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收
  12. long keepAliveTime,
  13. //枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等
  14. TimeUnit unit,
  15. //缓冲任务队列,线程池的execute方法会将Runnable对象存储起来
  16. BlockingQueue<Runnable> workQueue,
  17. //线程工厂接口,只有一个new Thread(Runnable r)方法,可为线程池创建新线程
  18. 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(一堆人排队上公厕)

[java] view plain copy

 
  1. /*
  2. *@FixThreadPool介绍
  3. *@author SEU_Calvin
  4. * @date 2016/09/03
  5. */
  6. public static ExecutorService newFixThreadPool(int nThreads){
  7. return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
  8. }
  9. //使用
  10. Executors.newFixThreadPool(5).execute(r);

(1)从配置参数来看,FixThreadPool只有核心线程,并且数量固定的,也不会被回收,所有线程都活动时,因为队列没有限制大小,新任务会等待执行。

(2)【前方高能,笔者脑洞】FixThreadPool其实就像一堆人排队上公厕一样,可以无数多人排队,但是厕所位置就那么多,而且没人上时,厕所也不会被拆迁,哈哈o(∩_∩)o ,很形象吧。

(3)由于线程不会回收,FixThreadPool会更快地响应外界请求,这也很容易理解,就好像有人突然想上厕所,公厕不是现用现建的。

2.2     SingleThreadPool(公厕里只有一个坑位)

[java] view plain copy

 
  1. /*
  2. *@SingleThreadPool介绍
  3. *@author SEU_Calvin
  4. * @date 2016/09/03
  5. */
  6. public static ExecutorService newSingleThreadPool (int nThreads){
  7. return new FinalizableDelegatedExecutorService ( new ThreadPoolExecutor (1, 1, 0, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()) );
  8. }
  9. //使用
  10. Executors.newSingleThreadPool ().execute(r);

(1)从配置参数可以看出,SingleThreadPool只有一个核心线程,确保所有任务都在同一线程中按顺序完成。因此不需要处理线程同步的问题。

(2)【前方高能,笔者脑洞】可以把SingleThreadPool简单的理解为FixThreadPool的参数被手动设置为1的情况,即Executors.newFixThreadPool(1).execute(r)。所以SingleThreadPool可以理解为公厕里只有一个坑位,先来先上。为什么只有一个坑位呢,因为这个公厕是收费的,收费的大爷上年纪了,只能管理一个坑位,多了就管不过来了(线程同步问题)。

2.3     CachedThreadPool(一堆人去一家很大的咖啡馆喝咖啡)

[java] view plain copy

 
  1. /*
  2. *@CachedThreadPool介绍
  3. *@author SEU_Calvin
  4. * @date 2016/09/03
  5. */
  6. public static ExecutorService newCachedThreadPool(int nThreads){
  7. return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit. SECONDS, new SynchronousQueue<Runnable>());
  8. }
  9. //使用
  10. Executors.newCachedThreadPool().execute(r);

(1)CachedThreadPool个线程的可能)处理任务。

(2)任务队列SynchronousQueue相当于一个空集合,导致任何任务都会被立即执行。

(3)【前方高能,笔者脑洞】CachedThreadPool就像是一堆人去一个很大的咖啡馆喝咖啡,里面服务员也很多,随时去,随时都可以喝到咖啡。但是为了响应国家的“光盘行动”,一个人喝剩下的咖啡会被保留60秒,供新来的客人使用,哈哈哈哈哈,好恶心啊。如果你运气好,没有剩下的咖啡,你会得到一杯新咖啡。但是以前客人剩下的咖啡超过60秒,就变质了,会被服务员回收掉。

(4)比较适合执行大量的耗时较少的任务。喝咖啡人挺多的,喝的时间也不长。

个里面唯一一个有延迟执行和周期重复执行的线程池)

[java] view plain copy

 
  1. /*
  2. *@ScheduledThreadPool介绍
  3. *@author SEU_Calvin
  4. * @date 2016/09/03
  5. */
  6. public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){
  7. return new ScheduledThreadPoolExecutor(corePoolSize);
  8. }
  9. public ScheduledThreadPoolExecutor(int corePoolSize){
  10. super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedQueue ());
  11. }
  12. //使用,延迟1秒执行,每隔2秒执行一次Runnable r
  13. Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);

(1)核心线程数固定,非核心线程(闲着没活干会被立即回收)数没有限制。

(2)从上面代码也可以看出,ScheduledThreadPool主要用于执行定时任务以及有固定周期的重复任务。

至此Android中最常见的四类不同特性的线程池内容总结完毕。

转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337

Android线程池(转)的更多相关文章

  1. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  2. android线程池ThreadPoolExecutor的理解

    android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...

  3. android 线程池的使用

    转自http://www.trinea.cn/android/java-android-thread-pool/ Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的 ...

  4. Android(java)学习笔记211:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  5. Android 线程池概念及使用

    一:使用线程池的原因 在android开发中经常会使用多线程异步来处理相关任务,而如果用传统的newThread来创建一个子线程进行处理,会造成一些严重的问题: 在任务众多的情况下,系统要为每一个任务 ...

  6. 最强大的Android线程池框架

    背景 大家都知道在我们的开发中永远都离不开多线程,对于我们为什么要使用多线程,多线程的使用和多线程的一些基础知识这里我们就不讲了,有兴趣的朋友可以去看一下博主之前的几篇文章: 线程你真的了解它吗 这才 ...

  7. -Android -线程池 批量上传图片 -附php接收代码

    (出处:http://www.cnblogs.com/linguanh/) 目录: 1,前序 2,类特点 3,用法 4,java代码 5,php代码 1,前序 还是源于重构,看着之前为赶时间写着的碎片 ...

  8. Java(Android)线程池

      1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run()  ...

  9. Android线程池(二)

    本篇主要介绍Android自带的线程池的管理. 包含开始任务.重新加载.添加删除任务等,示例代码如下: package com.jiao.threadpooltest; import java.uti ...

  10. Android线程池(一)

    本篇文章主要介绍Android自带的线程池的使用. 首先要引入线程池的概念 线程池:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务. 线程池线程都是后台线程.每个线 ...

随机推荐

  1. npm --- Node.js包管理器

    目录 1. 安装Node.js 2. 运行npm 3. npm介绍 3.1 安装插件 3.2 更新插件 3.3 卸载插件 3.4 查看当前目录中的插件列表 4. 使用cnpm 4.1 安装 npm( ...

  2. Azure Key Vault (3) 在Azure Windows VM里使用Key Vaule

    <Windows Azure Platform 系列文章目录> 本章我们介绍如何在Azure Windows VM里面,使用.NET使用Azure Key Vault 我们需要对Key V ...

  3. 【转】Cache Buffer Chain 第三篇

    文章转自:http://oracle.chinaitlab.com/induction/862509.html,文章前部分转载,后部分自己加上的. Oracle数据库只读模式的CACHE BUFFER ...

  4. Metatable In Lua 浅尝辄止

    http://www.cnblogs.com/simonw/archive/2007/01/17/622032.html 什么是Metatable Lua中Metatable这个概念, 国内将他翻译为 ...

  5. ZOJ3166【找环值最小】

    题意: 给你一幅图,要你找一个hotel能够满足出去回来,而且保证权值最小: 思路: 可以搜环,然后取最小权值环,拿个点: floyd方便,初始话自己到自己就是无穷,然后就枚举一下给出的hotel就好 ...

  6. HDU5113【DFS+剪枝】

    题意: n*m的矩阵 k种颜色 每种颜色有c[i]个 上下左右相邻的格子不能一样的颜色 问你有没有一种染色方法,有的话输出方案. 思路: 暴搜啊,n,m都才5,做完以后大哥的剪枝是奇偶剪枝,其实画完图 ...

  7. unity 在移动平台中,文件操作路径详解

    今天,这篇文章其实是个老生常谈的问题咯,在网上类似的文章也比比皆是,在此我只是做个详细总结方便大家能够更好.更快的掌握,当然,如有不足的地方 欢迎指正!!! 相信大家在开发过程中,难免会保存一些文件在 ...

  8. 51nod1076(tarjan)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1076 题意:中文题诶- 思路:先用tarjan找出所有桥,再用 ...

  9. uoj#282. 长度测量鸡(构造)

    传送门 打表题--只有\(n\leq 3\)有解否则无解→_→ 或者严格证明的话是这样,因为算上端点一共\(n+1\)个点,共\(\frac{n(n+1)}{2}\)个点对,所以点对之间两两距离不相等 ...

  10. Linux下安装ruby

    使用apt-get安装 sudo apt-get install ruby 这个命令下载的,有可能是旧的版本,所以还是推荐下面的方式. 下载tar.gz安装 去官方网站下载最新的tar.gz文件 su ...