线程分为主线程和子线程,主线程处理和界面相关的工作,子线程负责执行耗时操作。
除了Thread之外,还有一些特殊的线程,比如:AsyncTask、IntentService、HandlerThread。
AsyncTask:可以方便开发者在子线程中更新UI.
IntentService:是一个可以方便执行后台任务的服务,而且不容易被系统杀死。
HandlerThread:是一种具有消息循环的线程,在它的内部可以使用Handler。
1)AsyncTask<Params, Progress, Result>
4)工作原理:
注意:
在Android4.4.1系统上执行,AsyncTask是串行执行,Android2.3.1系统上是并行执行。
2)能有效控制线程池的最大并发数,避免大量线程之间抢占资源,而引起阻塞现象。
3)可以对线程进行简单管理,并提供定时执行等功能。
执行任务时遵循的规则:
除了Thread之外,还有一些特殊的线程,比如:AsyncTask、IntentService、HandlerThread。
AsyncTask:可以方便开发者在子线程中更新UI.
IntentService:是一个可以方便执行后台任务的服务,而且不容易被系统杀死。
HandlerThread:是一种具有消息循环的线程,在它的内部可以使用Handler。
一、Android中的线程形态
1、AsyncTask
是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行进度和结果传递到主线程,并更新UI。1)AsyncTask<Params, Progress, Result>
- -Params:参数的类型
- -Progress:后台任务执行进度的类型
- -Result:后台任务的返回结果的类型
- -onPreExecute():在异步任务执行之前调用,做一些准备工作
- -doInBackground(Params...params):执行异步任务,在此方法中可以通过publishProgress来更新任务进度。
- -onProgressUpdate(Progress...values):在任务的执行进度改变时会被调用。
- -onPostExecute(Result result):在异步任务执行完后调用,
还有一个onCancelled():当异步任务被取消时调用。3)使用过程中的条件限制:
- -第一次访问AsyncTask必须发生在主线程中
- -AsyncTask的对象必须在主线程中创建
- -不要在程序中直接调用四个核心方法
- -一个AsyncTask对象只能调用一次execute方法
4)工作原理:
- -先调用它的execute方法,execute内部会调用executeOnExecutor方法。
- -executeOnExecutor():内部onPreExecute()先执行,然后线程池SerialExecutor和THREAD_POOL_EXECUTOR开始执行。 -线程池SerialExecutor中:内部调用execute方法先把任务依次插入到任务队列中,如果这个时候没有正在活动的AsyncTask任务,那么就会调用scheduleNext()执行下一个AsyncTask任务,而scheduleNext()中的THREAD_POOL_EXECUTOR线程池用于真正执行任务。
- -WorkRunnable的call方法在线程池中执行:调用postResult(doInBackground(Params)),postResult方法会通过Handler发送MESSAGE_POST_RESULT的消息,接着Handler的handleMessage对消息MESSAGE_POST_RESULT进行处理,调用AsyncTask的finish方法,如果收到消息MESSAGE_POST_PROGRESS,则调用AsyncTask的onProgressUpdate方法。
- -AsyncTask的finish方法:如果AsyncTask被取消,则调用onCancelled方法,否则调用onPostExecute方法。
注意:
在Android4.4.1系统上执行,AsyncTask是串行执行,Android2.3.1系统上是并行执行。
2、HandlerThread
它继承了Thread,而且在run方法中引入了Looper,所以可以在HandlerThread中创建Handler。3、IntentService
1)第一次启动时,调用IntentService的onCreate方法:会创建一个HandlerThread,然后使用HandlerThread的Looper来构造一个Handler对象serviceHandler。
2)调用IntentService的onStartCommand方法:处理每个后台任务的Intent,通过serviceHandler发送一个消息,这个消息会在HandlerThread中处理,也就是在
serviceHandler的handleMessage中处理。
二、Android中的线程池
1、优点
1)重用线程池中的线程,减小性能开销。2)能有效控制线程池的最大并发数,避免大量线程之间抢占资源,而引起阻塞现象。
3)可以对线程进行简单管理,并提供定时执行等功能。
2、ThreadPoolExecutor
构造方法中各大参数的含义- 1)corePoolSize:线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,即使它们处于闲置状态。
- 2)maximumPoolSize:线程池所能容纳的最大线程数,当活动线程达到上限后,后续的新任务将会被阻塞。
- 3)keepAliveTime:非核心线程闲置时的超时时长,超过这个时长,非核心线程就会被回收。
- 4)unit;用于指定keepAliveTime的时间单位。
- 5)workQueue:线程池中的任务队列。
- 6)threadFactory:线程工厂,为线程池提供创建新线程的功能。
- 7)RejectedExecutionHandler:当任务队列已满或者无法成功执行任务时,会调用它的rejectedExecution来通知调用者。
执行任务时遵循的规则:
- 1)如果线程池中的线程数量未达到核心线程的数量,就会直接启动一个核心线程来执行任务。
- 2)如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待。
- 3)如果在2)中任务队列已满,这个时候如果线程数未达到线程池的上限,那么会立即启动一个非核心线程来执行。
- 4)如果在3)中线程数已达到线程池的上限,那么就拒绝执行此任务。
3、线程池的分类
1)FixedThreadPool
- -是一种线程数量固定的线程池
- -只有核心线程,没有超时机制
2)CachedThreadPool
- -是一种线程数量不定的线程池
- -只有非核心线程,并且最大线程数为Integer.MAX_VALUE
- -每个线程都有超时机制,时长为60s
- -适合执行大量的耗时较少的任务
- -几乎不占用任何系统资源
3)ScheduledThreadPool
- -是一种核心线程数量固定、非核心线程数量不定的线程池
- -用于执行定时任务和具有固定周期的重复任务
4)SingleThreadExecutor
- -只有一个核心线程,同一外界所有的任务到一个线程中
- -不需要处理线程同步的问题