Android开发艺术探索学习笔记6——线程和线程池
在安卓中开创线程的4中方式:
1、Thread 2、AsyncTask 3、IntentService4、HandlerThread
AsyncTask:(底层为线程池和handler)方便开发者在子线程中更新UI
HandlerTread:(底层使用线程)有消息循环的线程,内部可使用 Handler
IntentService:(底层直接使用了HandlerThread)内部采用了HandlerThread来执行任务,它不容易被系统杀死,并在执行任务完毕后退出。
Android中的线程形态:
AsyncTask:
AsyncTask是一种轻量级的异步任务类,内部封装了Thread和Handler,可以方便地执行后台任务以及在主线程中访问UI。但是其并不适合特表好使的任务。(特别耗时还是用线程池)。
基本使用
AsyncTask中的四个核心方法:
1、 pnPreExecute:
主线程中执行。一般做用于做准备工作
2、 doInBackGround:
线程池中执行。用于执行异步任务。次方法可以通过pubilishProgress来更新进度,其会回调onProgress
3、 onProgressUpdare:
主线程中执行。后台任务执行进度发生改变时调用
4、 onPsotExecute:
在主线程中执行。
AsyncTask注意点
1、 只能在主线程创建和调用
2、 一个AsyncTask只能执行一次execute方法,否则异常
3、 AsyncTask在执行任务时是串行的
AsyncTask的工作原理:
SerialExecutor:底层通过poll将任务放入队列。然后将任务逐一拿出进行执行(scheduleNext)。是串行执行的。
内部handler因为要在主线程进行更新,因此AsyncTask必须在主线程中创建。同时由于handler是以静态变量的形式存在,所以必须在主线程中加载。
(其在Android2.3.3的时候是并行地,在Android4.1.1之后变成了串行执行)
HandlerThread
它继承了Thread,也就是说处理一切东西都是在自己的线程中。
特点:
1、 对于普通Handler来说handler.post可以发送线程,单始终是在主线程中执行。而HanderThread发送的线程,真的是一个新的线程。
2、 它运行的内容都在自己的线程中
InentService:
Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。
InentService创建了一个独立的工作线程来处理后台耗时任务,当任务执行后他会自动停止。因为它是服务,它的优先级比单纯的线程高很多。它封装HandlerThread和Handler。如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,执行完自动结束。
HandlerThread:处理intentService中的异步请求。具体的handler由HanderThread的Looper构造出来。
Android中的线程池
优点:
l 重用线程池中的线程,避免因为线程创建和销毁所带来的性能开销
l 有效控制线程池的最大并发数,避免大量线程之间因为相互抢占系统资源而导致的阻塞
l 对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能。
ThreadPoolExecutor
ThreadPoolExecutor执行任务规则:
1、 未达到核心线程数量,先启动核心线程
2、 核心数量满,但线程池最大线程没满则插入队列,并启动非核心线程执行
3、 超过最大线程,则拒绝该任务。并通过RejectedExecutionHandler的rejectedExecution方法来通知调用者。
AsyncTask
它的内部配置的ExecutorHandler的规格如下:
l 核心线程数 等于cpu数+1
l 线程池的最大线程数为cpu*2+1
l 核心线程无超时机制,非核心线程在闲置时的超时时间为1秒
l 任务队列的容量为128
线程池分类:
1、 FixedThreadPool
固定线程数量,只有核心线程。
优点:能够更快
2、 CachedThreadPool
只有非核心线程
优点:执行大量的耗时较少的任务
3、 ScheduleThreadPool
核心线程固定,非核心线程无限制
优点:是和执行定时任务和具有固定周期的重复任务
4、 SingalThreadExecutor
只有一个核心线程
优点:确保所有的任务都在同一个线程中按顺序执行。