Android 的线程跟线程池

Android 的线程跟线程池

Android中线程分为主线程(进程所拥有的一个默认线程)跟子线程,主线程主要处理和界面相关的操作,而子线程则处理一些耗时操作,如从网络加载图片(从android3.0开始网络请求需放到子线程中处理),I/O操作等。(若主线程中执行耗时操作程序容易出现ANR)

线程:线程是操作系统调度的最小单元,也是一种受限制的系统资源,线程不能无限的产生,线程的创建跟销毁都会有相应的开销(这就导致了线程池的诞生)。注意线程不可能做到绝对的并行。

线程池:一个线程池会缓存一定数量的线程,并且线程池可以复用其内部的某些线程,以减少线程创建和销毁时的开销。

Android 线程形式(简单列举几例)

AsyncTask

AsyncTask是轻量级的异步任务类,其内部封装了Thread跟Handler(其并不适合进行特别耗时的后台任务)

其核心方法有4个:

onPreExecute() ,该方法是在主线程中执行,在异步任务开始之前做一些准备工作。

doInBackground(),该方法在线程池中执行,用于执行异步任务。另外此方法里面可以调用publishProgress方法来更新任务的进度(publishProgress方法会调用onProgressUpdate方法)。

onProgressUpdate(),该方法在主线程中执行,当任务进度改变时此方法会被调用。

onPostExecute()方法,在主线程中执行,任务完成之后调用。

另外还有onCancelled()方法,它在主线程中执行,用于取消异步任务。

使用AsynvTask时需注意:

1  AsyncTask的类必须在主线程中加载

2  AsyncTask对象必须在主线程中创建

3  execute方法必须在主线程中调用

4  不要在程序中直接调用onPreExecute,doInBackground,onProgressUpdate,onPostExecute方法。

5  一个AsyncTask对象只能执行一次。

HandlerThread

HandlerThread继承自Thread,特点是其run方法是一个无限循环的,当不需要使用HandlerThread时可以通过它的quit方法或者quitSafely方法终止线程。

其run的源码如下:

@Override

 public void run() {

    mTid = Process.myTid();

    Looper.prepare();

    synchronized (this) {

        mLooper = Looper.myLooper();

        notifyAll();

    }

    Process.setThreadPriority(mPriority);

    onLooperPrepared();

     Looper.loop();

    mTid = -1;

}

IntentService

IntentService是一种特殊的Service,是继承自service的抽象类。可用于执行一些后台耗时的操作,优点是当任务执行完后它会自动停止。(另外由于IntentService继承了service所以其优先级较高,不易被系统杀死)。用代码来理解其用法:

public class SelfIntentSerivce extendsIntentService {

 

         publicSelfIntentSerivce() {

                   super("SelfIntentService");

         }

         @Override

         protectedvoid onHandleIntent(Intent intent) {

                            Stringstr=intent.getExtras().getString("service");

                            LogUtil.d("intent-serviceonHandleIntent"+str);

         }

         @Override

         publicvoid onCreate() {

                   super.onCreate();

                   LogUtil.d("intent-servicecreate");

         }

         @Override

         publicvoid onStart(Intent intent, int startId) {

                   super.onStart(intent,startId);

                   LogUtil.d("intent-servicestart "+intent.getExtras().getString("service"));

         }

         @Override

         publicvoid onDestroy() {

                   super.onDestroy();

                   LogUtil.d("intent-servicedestory");

         }

}

 

Intent intent=newIntent(this,SelfIntentSerivce.class);

intent.putExtra("service","hello");

startService(intent);

运行结果如下:

Android 的线程跟线程池_第1张图片Android 的线程跟线程池_第2张图片

当IntentService任务执行完成后其会自动结束。

Android的线程池

线程池的优点有:

1可以重用线程池中的线程以减少线程创建跟销毁带来的性能开销

2克有效控制线程池的最大并发数,避免大量线程之间相互抢占系统资源导致阻塞

3能管理其内部的线程,并提供定时执行跟指定时间间隔执行。

ThreadPoolExecutor

ThreadPoolExecutor是线程池的实现类,其构造方法提供一系列参数来配置线程池。

其有多个构造方法,举一个为例:

public ThreadPoolExecutor(int corePoolSize,

                      int maximumPoolSize,

                      long keepAliveTime,

                      TimeUnit unit,

                     BlockingQueue<Runnable> workQueue,

                      ThreadFactorythreadFactory) {

 this(corePoolSize, maximumPoolSize,keepAliveTime, unit, workQueue,

            threadFactory, defaultHandler);

 }

corePoolSize:代表线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,即便是核心线程处于闲置状态。若ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的核心线程在等待新任务的到来时会有超时策略,这个时间间隔由keepAliveTime决定,当等待时间超过keepAliveTime所指定的时间后,核心线程就会被终止。

maximumPoolSize:线程池的最大线程数,当活动的线程达到这个数值后,后续的新任务将会被阻塞。

keepAliveTime:非核心线程闲置时的超时时长,超过这个时间,非核心线程会被回收,当ThreadPoolExecutor的allowCoreThreadTimeOut设置为true时,其同样会作用于核心线程。

Unit:用于指定keepAliveTime参数的时间单位,有TimeUnit.MILLISECOND,TimeUnit.SECOND等。

WorkQueue:线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中。

threadFactory:线程工厂,为线程池提供创建新线程的功能。

 

ThreadPoolExecutor执行任务规则如下:

1: 线程池中的线程数未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。

2 :线程池中的线程数已经达到或超过核心线程数量,那么任务会被插到任务队列中排队等待执行

3: 如果2中的任务无法插到任务队列中(比如任务队列满了),这时候如果线程数量未达到线程池规定的最大值,则会启动一个非核心线程来执行。

4 :如果 3中线程数已经达到线程池最大值,那么就会拒绝执行这个任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectExecution方法来通知调用者。

你可能感兴趣的:(android,线程,线程池,异步)