Android的线程和线程池————读书笔记

Android的线程和线程池

从用途上来讲,线程分为主线程和子线程,主线程主要处理和界面相关的事情,而子线程则往往用于执行耗时操作。
AsyncTask封装了线程池和Handler,它主要为了方便开发者在子线程中更新UI。HandlerThread是一种具有消息循环的线程,在它的内部可以使用Handler。IntentService是一个服务,系统对其进行了封装使其可以方便的执行后台任务,IntentService内部采用HandlerThread来执行任务,当任务完毕后IntentService会自动退出。

Android中的线程形态

AsyncTask

AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把进度和最终结果传递给主线程中更新UI。(不适合耗时任务,耗时任务可用线程池)

public abstract class AsyncTask<Params, Progress, Result>

提供了四个核心方法:
1. onPreExecute(),主线程中执行,在异步任务执行前被调用。
2. doInBackground(Params..params),在线程池中执行,用于异步任务,params表示异步任务的输入参数。
3. onProgressUpdate(Progress..values),主线程中执行,当后台任务执行进度改变被调用。
4. onPostExecute(Result result),在主线程中执行,在任务后被调用。
AsyncTask的条件限制:
1. AsyncTask的类必须在主线程中被加载。
2. AsyncTask的对象必须在主线程中被创建。
3. excute方法必须在UI线程中调用。
4. 不要在程序中直接使用onPreExecute,doInBackground,onProgressUpdate,onPostExecute方法。
5. 一个AsyncTask对象只能执行一次。
6. Android3.0以后采用一个线程串行执行任务

AsyncTask的工作原理

    @MainThread
    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                case RUNNING:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task is already running.");
                case FINISHED:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task has already been executed "
                            + "(a task can be executed only once)");
            }
        }

        mStatus = Status.RUNNING;

        onPreExecute();

        mWorker.mParams = params;
        exec.execute(mFuture);

        return this;
    }

sDefaultExecutor实际上是一个串行的线程池。
下面分析线程池的执行过程:

private static class SerialExecutor implements Executor {
    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
    Runnable mActive;

    public synchronized void execute(final Runnable r) {
        mTasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });
        if (mActive == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((mActive = mTasks.poll()) != null) {
            THREAD_POOL_EXECUTOR.execute(mActive);
        }
    }
}

AsyncTask有两个线程池(SerialExecutor 和 THREAD_POOL_EXECUTOR)和一个Handler,其中SerialExecutor 用于任务的排队,THREAD_POOL_EXECUTOR用于真正执行任务,IntentHandler用于将执行环境从线程池切换到主线程

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                // There is only one result
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
        }
    }
}

sHandler是一个静态Handler对象,为了能够将执行环境切换到主线程,这就要求sHandler这个对象必须在主线程中创建。

HandlerThread

HandlerThread继承了Thread,它是一种可以使用Handler的Thread,实现很简单,在run方法中通过Looper.prepare来创建消息duil,并通过Looper.loop来开启消息循环

IntentService

IntentService是一种特殊的Service,它继承了Service并且它是一个抽象类,因此必须创建它的子类才能使用IntentService。

Android中的线程池

线程池的有点:
1. 重用线程池中的线程,避免线程的创建和销毁所带来的性能开销
2. 能有效控制线程池中的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
3. 能够对线程进行简单的管理,并提供定时执行以及制定时间间隔循环执行等功能。
Java中的Executor是一个接口,真正的线程池的实现为ThreadPoolExecutor。

ThreadPoolExecutor分为四类:FixedThreadPool、CacheThreadPool、ScheduledThreadPool以及SingleThreadexecutor.

你可能感兴趣的:(线程,android,读书笔记,线程池)