一,Android中的线程形态
- AsyncTask
class Asy extends AsyncTask<String,Integer,String>{
@Override
protected void onPreExecute() {//异步任务执行前准备工作
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
//在线程池中执行异步任务
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//更新执行进度
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//执行异步任务结束后,s为返回的结果
}
}
AsynTask在具体的使用中的限制
(1)AsynTask的类必须在主线程中加载
(2)AsynTask对象必须在主线程中创建
(3)execute方法必须在UI线程调用
(4)不要在程序中直接调用 onPreExecute(),onPostExecute(),doInBackground,onProgressUpdate();
(5)一个AsynTask对象只能执行一次,即只能调用execute方法。否则报异常
-
HandlerThread
HandlerThread集成了Thread并且在内部实现了Looper.prepare()和Looper.Loop()l
可通过quit 或者quitSafely(api18加入的)方法来终止线程
两者都不会接收新的消息
区别在于
quit会清空所有消息,包括延迟消息,非延迟消息
quitSafely会清空所有延时消息,不会情况分延迟消息 会发送分延迟消息 -
IntentService
IntentService 是继承于 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 那么,用 IntentService 有什么好处呢?首先,我们省去了在 Service 中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止 Service。
IntentService是Service 的子类,默认给我们开启了一个工作线程执行耗时任务,并且执行完任务后自 动停止服务。扩展IntentService比较简单,提供一个构造方法和实现onHandleIntent 方法就可了,不用重写父类的其他方法。但是如果要绑定服务的话,还是要重写onBind 返回一个IBinder 的。使用Service 可以同时执行多个请求,而使用IntentService 只能同时执行一个请求。
-
Android中的线程池
(1)重用线程池中的线程,避免多次的创建销毁带来的性能开销
(2)能有效地控制线程的最大的并发数,防止因想线程之间互相抢占资源导致阻塞现象
(3)能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能。
Android中线程池主要是通过配置ThreadPoolExecutor来实现的
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
corePoolSize:
线程池的核心线程数
默认情况下核心线程会一直存活,及时处于闲置状态,但是如果制定了allowCoreThreadTimeOut为true则 会有超时策略 超时后会核心线程就会终止,这个超时时间是由keepAliveTime来设定的
maximumPoolSize:
线程池中容纳的最大线程数,如果线程数达到这个值 新的线程进入会被阻塞
keepAliveTime
闲置时的超时时间
unit
设置keepAliveTime的单位
workQueue
线程池中的任务队列,通过线程池的execute方法提交的runnable对象会存储在这个参数中
threadFactory
线程工程,为线程池提供创建新线程的功能,它是一个接口,只有一个方法Thread new Thread(Runnable r)
ThreadPoolExecutor执行任务的大致规则
1.如果线程池中的核心线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。
2.如果线程池中的线程数量已经达到或者超过核心线程数量,那么任务会被插入到任务队列中排队等待执行
3.如果步骤2中无法将任务插入到任务队列中,这种情况往往是因为任务队列已经满了,这个时候如果线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行。
4.如果三步骤线程数量达到线程池规定的最大值,那么就会拒绝这个任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知使用者。
线程池的分类
1,fixedThreadPool
它是一种固定线程池数量的线程池,只有核心线程,处于空闲状态,他们并不会被回收,除非线程池关闭。他没有超时机制,也没有任务队列的大小限制。其优势在于可以更加快速的响应外界请求
2.CachedThreadPool
线程池数量不定,只有非核心线程,最大线程数值为Integer.MAX_VALUE,这个值趋于无限大。
有闲置线程就用闲置线程,没有就新建线程,超时时长为60秒。
它相当于一个空集合,任何任务都会立刻执行。
它适合执行大量耗时较少的任务。
3.ScheduledThreadPool
核心线程数量固定,非核心线程数没有限制。
非核心线程限制会立刻回收
主要用于执行定时任务,具有固定周期重复性任务。
4.singleThreadExecutor
只有一个核心线程,确保所有任务在同一个线程中按顺序执行。
不需要处理线程同步问题。
网友评论