异步任务的正确使用

1、线程

注意线程是可以设置优先级的

new Thread(new Runnable() {
            @Override
            public void run() {
                //设置线程优先级,减少与UI线程的竞争
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            }
        }).start();


特定场景下(例如App启动阶段为避免在主线程创建线程池的资源消耗)使用的话务必加上优先级的设置,而且在启动阶段这样创建线程的开销要小于创建线程池的开销

2、正确使用AsyncTask

参考:

可以方便的进行线程切换,并且线程的优先级已经被默认设置成了:THREAD_PRIORITY_BACKGROUND,不会与UI线程抢占资源

AsyncTask中的任务默认是放入ArrayDeque中,串行执行,正确使用AsyncTask的串行与并行

3、线程池的使用
package com.miduo.glidestudy;

import android.os.Process;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadManager {

    private static ThreadPoolProxy mShortPool = null;
    private static Object mShortLock = new Object();

    public static void execute(final ThreadRunnable runnable)
    {
        getShortPool().execute(new Runnable() {
            @Override
            public void run() {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                runnable.doInBackGround();
            }
        });


    }

    abstract static class ThreadRunnable{

        abstract void doInBackGround();

    }






    /** 获取一个用于执行短耗时任务的线程池,避免因为和耗时长的任务处在同一个队列而长时间得不到执行,通常用来执行本地的IO/SQL */
    public static ThreadPoolProxy getShortPool() {
        synchronized (mShortLock) {
            if (mShortPool == null) {
                mShortPool = new ThreadPoolProxy(2, 2, 5L);
            }
            return mShortPool;
        }
    }

    public static class ThreadPoolProxy {
        private ThreadPoolExecutor mPool;
        private int mCorePoolSize;
        private int mMaximumPoolSize;
        private long mKeepAliveTime;

        private ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
            mCorePoolSize = corePoolSize;
            mMaximumPoolSize = maximumPoolSize;
            mKeepAliveTime = keepAliveTime;
        }

        /** 执行任务,当线程池处于关闭,将会重新创建新的线程池 */
        public synchronized void execute(Runnable run) {
            if (run == null) {
                return;
            }
            if (mPool == null || mPool.isShutdown()) {
                //参数说明
                //当线程池中的线程小于mCorePoolSize,直接创建新的线程加入线程池执行任务
                //当线程池中的线程数目等于mCorePoolSize,将会把任务放入任务队列BlockingQueue中
                //当BlockingQueue中的任务放满了,将会创建新的线程去执行,
                //但是当总线程数大于mMaximumPoolSize时,将会抛出异常,交给RejectedExecutionHandler处理
                //mKeepAliveTime是线程执行完任务后,且队列中没有可以执行的任务,存活的时间,后面的参数是时间单位
                //ThreadFactory是每次创建新的线程工厂
                mPool = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
            }
            mPool.execute(run);
        }

        /** 取消线程池中某个还未执行的任务 */
        public synchronized void cancel(Runnable run) {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {//(线程池没有关闭或者说正在关闭,但还没有完全关闭)
                mPool.getQueue().remove(run);
            }
        }

        /** 判断线程池中是否包含指定的任务 */
        public synchronized boolean contains(Runnable run) {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                return mPool.getQueue().contains(run);
            } else {
                return false;
            }
        }

        /** 立刻关闭线程池,并且正在执行的任务也将会被中断 */
        public void stop() {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                mPool.shutdownNow();
            }
        }

        /** 平缓关闭单任务线程池,但是会确保所有已经加入的任务都将会被执行完毕才关闭 */
        public synchronized void shutdown() {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                mPool.shutdown();
            }
        }
    }

}

参考

线程的优先级具有继承性,在某线程中创建的线程会继承此线程的优先级。那么我们在UI线程中创建了线程池,其中的线程优先级是和UI线程优先级一样的;所以仍然可能出现20个同样优先级的线程平等的和UI线程抢占资源

在上面的示例中,我们设置了线程池中的线程的优先级为
THREAD_PRIORITY_BACKGROUND,AsyncTask就是这么用的

你可能感兴趣的:(异步任务的正确使用)