Android线程和线程池

线程是系统调度的最小单位。

Android主线程和子线程

主线程用于运行四大组件及用户的交互,

子线程用于执行耗时任务,网络请求,io操作等

AsyncTask

AsyncTask封装了线程池和Handler,是一种轻量级的异步任务类,特别耗时的任务不建议使用。有几个核心方法:

onPreExecute(),任务执行前调用在主线程执行

doInBackGround(),在子线程执行,可以在内部调用publishProgress()方法更新任务的进度调用该方法会调用onProgressUpdate()方法,在doInbackGround()中需要将结果返回

onProgressUpdate(),在主线程中执行,可以用于更新ui

onPostExcute(),得到doInBackGround的结果

onCanceled(),异步任务被取消时被调用。

调用excute()启动任务执行流程

那看看AsyncTask的excute方法源码:

@MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

调用了excuteOnExcutor(),跟进去看看

  @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;
    }

调用了Excutor的execute方法,看看

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);
            }
        }
    }

可以看到SerialExcutor的execute用于将任务的调度,THREAD_POOL_EXECUTOR才是执行任务的线程池,mActive是在任务队列里的Runnable对象,执行完之后如何返回结果呢

/**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     */
    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                Result result = doInBackground(mParams);
                Binder.flushPendingCommands();
                return postResult(result);
            }
        };

        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(get());
                } catch (InterruptedException e) {
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }

看构造函数中调用postResult()将结果返回

private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

postResult使用handler发送了一个消息,来看看这个handler的handlemessage()处理,

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;
            }
        }
    }

调用了finish()

private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

和onProgressUpdate()将结果返回到了ui线程处理,所以该handler必须要在主线程创建,这也要求了AsyncTask必须在ui线程创建

==使用注意事项==

1.AsyncTask必须在主线程中加载,在4.1以上版本系统已经替我们做好了,

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

3.execute必须在主线程中执行

4.注意3.0之后AsyncTask是串行执行任务的,但可以使用executeOnexcutor()方法使用自定义的线程池用于执行任务,1.6到3.0是并行的,

HandlerThread

是个继承了Thread的内部创建了Looper和消息队列的类,所以可以在使用它来创建handler,其run方法是个死循环,需要及时使用looper.quit()退出线程。
该类用于IntentService

IntentService

IntentService是继承自Service的抽象类,用于执行后台任务,内部使用了HandlerThread,优先级比普通的线程高,不容易被系统杀死。

IntentService第一次启动时onCreate会执行创建HandlerIntent对象,以后每次启动调用onStartcommand()方法,其中将intent做为消息发送给用HandlerThread对象创建的handler,在handler的handlemessage()中调用了onhandleintent()方法,执行完所有后台任务会调用stopself(),service结束自己。

Android的线程池

线程池的作用:

重用线程池中的线程,避免因为线程的创建、销毁所带来的性能开销。

控制并发数量,避免线程之间互相抢占系统资源而导致的阻塞现象,

能够对线程进行管理,定时或延时

java的Executor为线程池类接口,实现类为threadPoolExcutor,通过配置该类的参数,Android线程池可以分为四类

构造函数

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

corePoolSize:核心线程数,默认情况,核心线程会一直存活,及时他们处于闲置状态,如果allowcoreThreadtimeout设为true,那么闲置的核心线程在等待新任务到来时会有超时策略,时间超过了keepAliveTime后会终止。

maximumPoolSize:最大线程数,线程数达到最大后后续的任务会被阻塞

keepAliveTime:非核心线程的超时时长,也作用与核心线程。

unit :超时时长的单位

workQueue:线程池的任务队列,execute方法提交的runnable会存入这里。

threadFactory: 为线程池提供创建线程的功能。接口,只有newthread()方法

RejectedExecutionHandler,在无法执行新任务情况下的回调接口

线程池的调度规则

1.如果线程池的核心线程未满,则新任务会创建新县城

2.如果线程池数量已经达到或者超过核心线程,那么任务会放入任务队列等待

3.如果任务队列已满,线程数未达到最大值,会启动一个非核心线程。

4.如果任务队列已满,会执行构造函数最后一个参数的回调

来看看Android的AsyncTask线程池配置

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);


    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;

四类线程池

fixedThreadPool,固定核心线程数,没有非核心,不会回收,响应速度块

CachedThreadPool,没有核心线程,任意非核心,用于处理 大量的耗时少的任务,没有线程数的限制,没有任务个数限制,超时停止

ScheduledThreadPool,固定核心,任意非核心,非核心闲置时会被回收,用于执行定时任务和固定周期的任务。

SingleThreadExcutor,只哟一个核心线程,单线程执行,不需要同步

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值