一. 线程分类

线程主要分为主线程跟子线程。

  • 主线程
    主线程,也叫UI线程。主要处理界面交互的逻辑。我们不能在主现场中执行耗时操作,因为这样会造成界面卡顿,用户体验不好,甚至会引起ANR,导致应用崩溃。

  • 子线程
    子线程,也叫工作线程,主要处理主线程不能处理的耗时操作,比如网络请求,数据库操作,IO操作。

二. 线程表现形式

在Android中,线程的承载形式主要有Thread,AsynTask,IntentServices,HandleThred。

1.AsynTask

AsynTask是一个轻量级执行异步任务的类,主要作用就是在后台执行耗时任务,然后把耗时的任务到进度跟返回值反馈到主线,让主线做相应的UI更新操作。它底层使用的是Thred跟Handler。

1.1 AsynTask的基本使用

AsynTask是一个抽象的泛型类它提供了Params,Progress,Result三个泛型参数。

public abstract class AsyncTask<Params, Progress, Result>

  • Params:表示AsynTask执行异步任务的时候的参数类型,比如下载文件的时候的Url
  • Progress:后台执行任务的进度类型
  • Result:后台执行任务完成返回的结果类型

AsynTask一般需要重写四个方法
onPreExecute():在执行异步任务的之前会调用,用于前期准备工作。

doInBackground(Params…params):用于执行异步任务

onProgressUpdate(Progress…progress):当异步任务的进度发生变化的时候调用。注意:这个方法不会自动执行,需要手动在
doInBackground方法里面通过调用publishProgress方法,publishProgress才会调用onProgressUpdate方法更新进度,该方法是在主线程中执行。

onPostExecute(Result result) :在异步任务执行完成之后,该方法就会被调用,result值就是doInBackground返回值。

这个四个方法执行执行次序就是:
onPreExecute->doInBackground->onProgressUpdate->onProgressUpdate

2.HandlerThread

HandlerThread是一个比较特殊的Thread类,让我们看看它一部分源码

public void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}

通过源码,我们很容易得知它内部创建了消息队列。一般情况下,HandlerThread其中使用场景就是IntentServices。

2.1 HandlerThread的简单使用

HandlerThread mThread = new HandlerThread("线程名称");
mThread.start();

注意:因为HandlerThread内部使用了Looper消息轮训,我们知道Looper的轮训是一个死循环,所以当我们不用HandlerThread的时候需要手动去通过Looper的quiet或者quietSafely方法去停止它

3.IntentService

IntentService是Service的子类,它主要用于执行后台耗时任务,当任务执行完成之后,就会自动停止。它的好处就是当我们需要在后台执行耗时任务的时候,可以不用重新创建启动线程,当任务完成之后不用管理该服务的生命周期。它内部使用的Handler跟HandlerThread。

3.1 IntentService简单实用

通过继承IntentService抽象类,然后复写onHandleIntent,把耗时的任务写在onHandleIntent里面。 然后通过context.startService(intent) 启动服务即可。
举个例子:

class  DownloadFileServices extends IntentService{public DownloadFileServices(String name) {super(name);}@Overrideprotected void onHandleIntent(Intent intent) {downloadFile();}} 

然后只要Activity启动服务就可以了

三. 线程池

当我们需要执行异步任务的时候,我们就会创建一个线程去实现,这样虽然很方便,如果过多创建线程的时候,就不可以避免的产生系统资源浪费的问题。如果需要解决这个问题,这时候就需要引入线程池了。线程池最主要作用就是重复使用线程,节省性能开销,同时还能对线程进行队列管理,防止线程之间互相抢占资源。

3.1 线程池的实现类-ThreadPoolExecutor

ThreadPoolExecutor实现线程池的实现类,构造函数中提供了一系列参数来配置线程池。

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

下面讲解一下这些参数的含义:
corePoolSize:线程池的核心线程数。如果allowCoreThreadTimeOut属性为false的情况,核心线程会一直存活在线程池。
maximumPoolSize:线程池能容纳的最大线程数量。
keepAliveTime:线程闲置的时候的超时时常。如果线程的属性allowCoreThreadTimeOut为true的时候,这个时间会作用于非核心线程跟核心线程,如果allowCoreThreadTimeOut为false的时候,这个时间只会作用于非核心线程。
unit:keepAliveTimed的时间单位
workQueue:线程池的任务队列。
threadFactory:线程工程,主要用于生产线程。
handler:线程无法执行任务的时候采用的策略。

3.2 线程池处理任务的方式

如果线程池中的核心线程未达到核心线程的数量,就会创建一个核心线程执行任务,如果核心线程数量已满,那么任务就被放入队列里面,直到队列任务也满了,才会创建非核心线程来处理任务。如果队列满了,线程数量也达到最大值,那么就会拒绝处理任务。

3.3 线程池的队列

  • ArrayBlockingQueue:基于数组的先进先出队列
  • LinkedBlockingQueue:基于链表的先进先出队列
  • SynchronousQueue:一个没有数据缓存区的阻塞队列,是一个比较特殊的队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
  • DelayedWorkQueue: 基于二叉树的队列

3.3 线程池的分类

  • FixedThreadPool

    核心线程数:固定
    非核心线程数:没有
    超时时间:无限制
    任务队列:LinkedBlockingQueue
    队列限制数量:无限制

  • CachedThreadPool

    核心线程数:没有
    非核心线程数:没有
    超时时间:60s
    任务队列:SynchronousQueue
    队列限制数量:无限制

  • ScheduledThreadPool

    核心线程数:固定
    非核心线程数:没有限制
    超时时间:0s,一限制就马上被回收
    任务队列:DelayedWorkQueue

  • SignleThreadExecutor

    核心线程数:一个
    非核心线程数:没有
    超时时间:没有限制
    任务队列:LinkedBlockingQueue
    队列限制数量:无限制

Android线程与线程池相关推荐

  1. android线程及线程池

    众所周知,在UI系统中进行一些耗时操作,都会导致卡顿现象,因为一次刷新在16ms,如果当次操作过了这个时间,那么用户就能感觉到明显的卡顿,甚至引起ANR . 对于这种情况,一般都是再起一个线程,进行一 ...

  2. 【Android 异步操作】线程池 ( 线程池使用示例 | 自定义线程池使用流程 | 自定义任务拒绝处理策略 | 完整代码示例 )

    文章目录 一.自定义线程池使用流程 二.自定义任务拒绝处理策略 三.完整代码示例 在博客 [Android 异步操作]线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTas ...

  3. 【Android 异步操作】线程池 ( Worker 简介 | 线程池中的工作流程 runWorker | 从线程池任务队列中获取任务 getTask )

    文章目录 一.线程池中的 Worker ( 工作者 ) 二.线程池中的工作流程 runWorker 三.线程池任务队列中获取任务 getTask 在博客 [Android 异步操作]线程池 ( 线程池 ...

  4. 【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 )

    文章目录 一.线程池 reject 拒绝任务 二.线程池 addWorker 添加任务 在上一篇博客 [Android 异步操作]线程池 ( 线程池 execute 方法源码解析 ) 中 , 讲解 线 ...

  5. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

  6. Android多线程操作——线程池管理综述

    1 前言 android开发,大家最熟悉的肯定是主线程,也就是ui线程,也都知道在非ui线程更新界面会报错提示不允许在子线程更新ui.但是耗时操作还是需要使用子线程,如: new Thread(new ...

  7. android 线程池 怎么用,android中的线程池 怎么用

    满意答案 qpierq0n5 2016.05.02 采纳率:52%    等级:13 已帮助:8164人 //在Android中实现线程池,首先需要实现一个线程工厂(ThreadFactory)的子类 ...

  8. Android 中的线程池

    为什么使用线程池? 1.重用线程,防止频繁的创建销毁线程所带来的时间和资源等性能损耗. 2.有效的控制最大线程并发数,防止大量线程抢夺系统资源引起卡顿,合理利用系统资源. 3.对线程进行简单管理.以及 ...

  9. Android日记之线程池

    前言 在编程中经常会使用线程来异步处理任务,但是每个线程的创建和销毁都需要一定的开销.如果每次执行一个任务都需要一个新进程去执行,则这些线程的创建和销毁将消耗大量的资源:并且线程都是"各自为 ...

最新文章

  1. :架构优化在何时,方成为公司的推动力与核心竞争力
  2. 题解 DTOJ #1438. 矮人排队(lineup)
  3. 李东生:管理者不能变成诸葛先生
  4. 开源 免费使用 打包下载自行部署 :升讯威 周报系统
  5. 本人对于netty框架的一些理解,怎么与网站上的websock建立连接
  6. 【C语言】输入一个整数x并判断x是否存在于数组a中
  7. python如何对excel两个单元格求乘积_excel表格怎么求乘积_excel表格多个单元格怎么求积...
  8. MySQL LIKE 子句
  9. 为SSD加速 实战4KB对齐技巧3/3
  10. 扫描仪没有linux 驱动怎么安装,扫描仪驱动安装不上怎么办_扫描仪驱动安装方法 - 驱动管家...
  11. matplotlib4 --设置line的属性, color,linestyle, linewidth, marker等
  12. 计算机rankeq函数,Excel中的rank函数与rank.eq函数有什么区别
  13. Win7旗舰版下安装SQL Server 2008总结
  14. 批量生成pdf书签目录之目录自动格式化(Python实现)
  15. 实操:WDS安装win系统
  16. ios 获取是否静音模式_iOS 判断设备是否静音
  17. 益聚星荣:核心数据持续上扬,亏损持续扩大,我们究竟该如何看待B站?
  18. win7系统msi文件无法安装历程
  19. Android项目架构图
  20. 基于PySpark的航天日志分析(SQL分析)

热门文章

  1. php开源程序 流量统计,5款开源的PHP网站流量统计应用程序 -管理资料
  2. 爬取微博全部一级评论(简单有效)
  3. php对接短信宝,thinkphp短信宝发送短信
  4. 非黑!也不是刺激战场粉!我来说说我用安卓模拟器玩全军出击那些事儿
  5. oracle创建用户及修改密码
  6. IP地址、子网、子网掩码、网关、网段、路由端口地址、路由表、等
  7. 操作系统的备份与还原
  8. MATLAB GUIDE入门1
  9. 你要的七夕文案,已为您整理好!
  10. BTC transaction rawtx 解析