Android

Android的线程和线程池

2020-03-22  本文已影响0人  和莱

除了Thread,在Android中扮演线程角色的还有AsyncTask、HandleThread、intentService。它们的底层都用到了线程。AsyncTask封装了线程池和Handle,用于在子线程中更新UI,ThreadHandle中使用了Handle,IntentService是一种服务,比线程优先级更高,可以执行优先级更高的后台任务而不会被操作系统杀死。

AsyncTask

AsyncTask是一种轻量级异步任务,它可以在线程池中执行异步任务,然后将执行进度和执行结果传递给主线程,在主线程中更新UI,AsyncTask是一个抽象的泛型类,需要三个泛型参数,Params、Progress、Result,它提供了四个核心方法:onPreExecute,在主线程中执行,在执行异步任务前调用此方法,做一些准备工作;doInBackground,在线程池中执行,用于执行具体的异步任务;onUpdateProgress,在主线程中执行,当任务进度发生改变时调用此方法,更新任务进度;onPostExecute,异步任务结束以后调用此方法,在主线程中执行。

AsyncTask的工作原理是在UI线程中调用它的execute方法,这个方法又会调用executeOnExecute方法,然后这个方法在调用了onPreExecute方法之后,又会调用线程池的execute方法,将任务交到线程池中执行。异步任务默认是串行执行的。执行完毕之后postResult方法会使用UI的Handle将线程切换到主线程中执行。
为了让AsyncTask在Android3.0以上的版本并行执行,可以使用executeOnExecute方法。

HandleThread

是一种可以使用Handle的线程,在run方法中调用Looper的prepare方法创建消息循环系统,调用loop方法开启消息循环,在实际的使用中就可以Handle了,外部线程可以使用这个Handle来给这个线程发送执行具体任务的消息。

IntentService

是一种特殊的服务,它继承了Service,但还是一个抽象类,必须创建它的子类才能使用,它封装了HandleThread和Thread,当IntentService对象第一次被创建的时候,onCreate方法会创建一个HandleThread,其他线程通过它的Handle将耗时任务发送给它来执行,每次启动IntentService,它的onStartCommand方法就会执行,这个方法调用onStart方法,onStart方法中通过Handle会调用sendMessage方法向消息队列中添加任务,Handle会调用onHandleIntent方法处理这个消息,处理完毕消息之后调用stopSelf(ID)结束。

线程池

线程池的概念来自Java的Executor类,在Android中真正可以实现线程池的是ThreadPoolExecutor,构造函数参数有corePoolSize,核心线程数量,在默认情况下核心线程会一直存活,但是如果将allowCoreThreadTimeOut属性设置为true的话,在超时以后也会被销毁;maximumPoolSize,线程池最大线程数,当已有线程到达这个值时,新的任务会被阻塞;keepAliveTime,普通线程闲置时的存活时间,如果将allowCoreThreadTimeOut设置为true的话,也适用于核心线程;unit是时间单位;workQueue,存储通过线程池的execute方法提交的Runnable对象;threadFaxtory,为线程池提供创建线程的功能,它是一个接口,只有thread new Thread(Runnable)一个方法,RejectExeceptionHandle参数,当线程池无法执行新的任务时,会抛出此错误。
执行任务时的调用规则:如果核心线程有空闲,将任务交给核心线程执行,如果核心线程没有空闲但是任务队列未满,将任务阻塞到队列中,如果队列已经满了,但是线程池中的线程数量未达到最大值,可以创建其他线程执行这个任务,如果线程已经到达最大数量,拒绝这个任务,并通知调用者。

线程池的分类:
fixedThreadPool,线程数量固定,处于空闲状态也不销毁;
cacheThreadPool,线程数量不限,可以创建最大值的线程,但是没有核心线程;
SecheduleThreadPool,核心线程固定,非核心线程不限;
singleThreadExecuteor,只有一个线程的线程池;

上一篇 下一篇

猜你喜欢

热点阅读