内容简介:在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制地产生,并且线程的创建和销毁都会有相应的开销。在 Android 中除了 Thread 以外,还有 AsyncTask、IntentService 以及 HandlerThread 都扮演着线程的角色。在 Java 中默认情况下一个进程只有一个线程,这个就是主线程,除主线程以外的线程都叫子线程,Android 沿用了同样的线程模型。AsyncTask 中有两个线程池(SerialExecutor 和 THREAD
在操作系统中,线程是操作系统调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制地产生,并且线程的创建和销毁都会有相应的开销。在 Android 中除了 Thread 以外,还有 AsyncTask、IntentService 以及 HandlerThread 都扮演着线程的角色。
主线程和子线程
在 Java 中默认情况下一个进程只有一个线程,这个就是主线程,除主线程以外的线程都叫子线程,Android 沿用了同样的线程模型。
Android 中的线程形态
AsyncTask
- AsyncTask 是一个轻量级的异步任务类,在线程池中执行后台任务,然后把进度和最终结果传递到主线程更新 UI。
-
AsyncTask 是一个抽象的泛型类,提供了
Params、Progress和Result三个泛型参数。如果不需要传递具体的参数,参数类型可以使用Void来代替。public abstract class AsyncTask <Params, Progress, Result>
-
AsyncTask 提供 4 个核心方法:
- onPreExecute() :在主线程中执行,一般用于做一些准备工作。
- doInBackground(Params… params) :在线程池中执行异步任务,params 为输入参数。在此方法中可以调用
publishProgress(Progress)方法来更新任务进度。最终需要返回结果给onPostExecute方法。 - onProgressUpdate(Progess… values) :在主线程中执行,任务进度更新时会调用此方法。
- onPostExecute(Result result) :在主线程中执行,result 为异步任务中返回的结果。
- AsyncTask 使用时的注意点:
- AsyncTask 的类必须在主线程中加载,这一过程在 Android 4.1 及以上版本被系统自动完成(ActivityThread 的
main方法会调用 AsyncTask 的init方法)。 - AsyncTask 的对象必须在主线程中创建。
-
execute方法必须在 UI 线程中调用。 - 不要在程序中直接调用
onPreExecute、onPostExecute、doInBackground和onProgressUpdate方法。 - 一个 AsyncTask 对象只能执行一次,即只能调用一次
execute方法,否则会报错。 - 在 Android 1.6 之前,AsyncTask 是串行执行任务的,Android 1.6 的时候开始采用线程池处理并行任务,但是从 Android 3.0 开始,又换回了串行执行任务的方式,不过我们可以通过
executeOnExecutor方法执行并行任务。
- AsyncTask 的类必须在主线程中加载,这一过程在 Android 4.1 及以上版本被系统自动完成(ActivityThread 的
AsyncTask 的工作原理
AsyncTask 中有两个线程池(SerialExecutor 和 THREAD_POOL_EXECUTOR)和一个 Handler(InternalHandler)。其中线程池 SerialExecutor 用于任务的排队,而线程池 THREAD_POOL_EXECUTOR 用于真正地执行任务,InternalHandler 用于将执行环境从线程池切换到主线程。
HandlerThread
- HandlerThread 继承了 Thread,它是一种可以使用 Handler 的 Thread。
- HandlerThread 的实现就是在其
run方法中通过Looper.prepare()来创建消息队列,通过Looper.loop()来开启消息循环。 - HandlerThread 的
run方法是一个无限循环,当不需要使用时,要通过quit或者quitSafely方法来终止线程。 - HandlerThread 的一个典型使用场景就是 IntentService。
IntentService
-
IntentService 是一种特殊的抽象 Service,内部封装了 HandlerThread 和 Handler,比较适合执行一些高优先级的后台任务,不容易被杀死。
@Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } -
IntentService 调用
stopSelf(int startId)方法来尝试停止服务,会等待所有消息都处理完毕后才真正终止服务。 - IntentService 的执行顺序是按外界发起的顺序去执行的。
Android 中的线程池
- 线程池的优点:
- 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。
- 能有效控制线程池的最大并发数,避免大量线程之间因互相抢占系统资源而导致的阻塞现象。
- 能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能。
- Android 中线程池的概念源于 Java 中的 Executor,真正实现为 ThreadPoolExecutor。
ThreadPoolExecutor
ThreadPoolExecutor 常用构造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
- corePoolSize :线程池的核心线程数,默认情况下核心线程会一直存活。如果将 ThreadPoolExecutor 的
allowCoreThreadTimeOut属性设置为 true,闲置时间超过 keepAliveTime 会被终止。 - maximumPoolSize :线程池所能容纳的最大线程数(核心线程 + 非核心线程),当活动线程数达到这个数值后,后续任务会被阻塞。
- keepAliveTime :非核心线程闲置时的超时时长,超过这个时长,非核心线程会被回收。当 ThreadPoolExecutor 的
allowCoreThreadTimeOut属性设置为 true 时,同样作用于核心线程。 - unit :指定 keepAliveTime 参数的时间单位。
- workQueue :线程池中的任务队列,通过线程池的
execute方法提交的 Runnable 对象会被存储在这个参数中。 - threadFactory :线程工厂,为线程池提供创建新线程的功能。
ThreadPoolExecutor 执行任务时大致遵循如下规则:
- 如果线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。
- 如果线程池中的线程数量达到或超过核心线程的数量,那么任务会被插入任务队列等待执行。
- 如果步骤2中无法将任务插入任务队列中,这往往是由于任务队列已满,这时如果线程数量未到达线程池规定的最大值,那么会立即启动一个非核心线程来执行任务。
- 如果步骤3中的线程数量已经达到了线程池规定的最大值,那么就会拒绝执行此任务。
线程池的分类
Android 中最常见的四类线程池都是通过 Executors 的静态方法创建的。
-
FixedThreadPool- 线程数量固定的线程池,只有核心线程
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } -
CachedThreadPool- 线程数量不固定的线程池,只有非核心线程
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } -
ScheduledThreadPool- 核心线程数量固定,非核心线程数量没有限制的线程池,主要用于执行定时任务和具有固定周期的任务
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()); } -
SingleThreadExecutor- 只有一个核心线程的线程池,确保了所有的任务都在同一个线程中按顺序执行
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- java中线程安全,线程死锁,线程通信快速入门
- ObjC 多线程简析(一)-多线程简述和线程锁的基本应用
- Java多线程之线程中止
- iOS 多线程之线程安全
- java多线程 线程安全问题
- Java 多线程(二)—— 线程的同步
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Compilers
Alfred V. Aho、Monica S. Lam、Ravi Sethi、Jeffrey D. Ullman / Addison Wesley / 2006-9-10 / USD 186.80
This book provides the foundation for understanding the theory and pracitce of compilers. Revised and updated, it reflects the current state of compilation. Every chapter has been completely revised ......一起来看看 《Compilers》 这本书的介绍吧!