• AsyncTask: 为 UI 线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。
  • HandlerThread: 为某些回调方法或者等待某些任务的执行设置一个专属的线程,并提供线程任务的调度机制。
  • ThreadPool: 把任务分解成不同的单元,分发到各个不同的线程上,进行同时并发处理。
  • IntentService: 适合于执行由 UI 触发的后台 Service 任务,并可以把后台任务执行的情况通过一定的机制反馈给 UI。
    了解这些系统提供的多线程工具类分别适合在什么场景下,可以帮助我们选择合适的解决方案,避免出现不可预期的麻烦。虽然使用多线程可以提高程序的并发量,但是我们需要特别注意因为引入多线程而可能伴随而来的内存问题。举个例子,在 Activity 内部定义的一个 AsyncTask,它属于一个内部类,该类本身和外面的 Activity 是有引用关系的,如果 Activity 要销毁的时候,AsyncTask 还仍然在运行,这会导致 Activity 没有办法完全释放,从而引发内存泄漏。所以说,多线程是提升程序性能的有效手段之一,但是使用多线程却需要十分谨慎小心,如果不了解背后的执行机制以及使用的注意事项,很可能引起严重的问题。



    . Android 系统的屏幕刷新频率为 60 fps, 也就是每隔 16 ms 刷新一次。如果在某次绘制过程中,我们的操作不能在 16 ms 内完成,那它则不能赶上这次的绘制公交车,只能等下一轮。
    这种现象叫做 “掉帧”,用户看到的就是界面绘制不连续、卡顿。


    ThreadPoolExecutor 

    使用线程池的好处可以归纳为3点:
  1. 重用线程池中的线程, 避免因为线程的创建和销毁所带来的性能开销.
  2. 有效控制线程池中的最大并发数,避免大量线程之间因为相互抢占系统资源而导致的阻塞现象.
  3. 能够对线程进行简单的管理,可提供定时执行和按照指定时间间隔循环执行等功能.

不建议用ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor ();

而是用Executors工厂类方法

Executors类提供了4个工厂方法用于创建4种不同特性的线程池给开发者用.

区别:线程池的长度(线程的个数),可回收,是否处于等待状态,是否支持周期性

(1)newCachedThreadPool 创建一个可缓存线程池,线程池的最大长度无限制,但如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

   (2)   newFixedThreadPool  创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

(3)newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

(4)newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Overridepublic void run() { } },1, 2, TimeUnit.SECONDS);

常见几种BlockingQueue实现

     1. ArrayBlockingQueue :  有界的数组队列
  2. LinkedBlockingQueue : 可支持有界/无界的队列,使用链表实现
  3. PriorityBlockingQueue : 优先队列,可以针对任务排序
  4. SynchronousQueue : 队列长度为1的队列,和Array有点区别就是:client thread提交到block queue会是一个阻塞过程,直到有一个worker thread连接上来poll task。

  • android中的线程池都是直接或是间接通过配置ThreadPoolExecutor来实现的.

Executor和ExecutorService都是接口

Executor mThreadPool = Executors.newFixedThreadPool(3);
private ExecutorService  mThreadPool = Executors.newFixedThreadPool(3);
public interface ExecutorService extends Executor {

建线程池管理者 ThreadManager

public class ThreadManager {
    public static final int POOL_SIZE = 2;
    public static ThreadManager mThreadManager = null;
    private ExecutorService mExeService = null;
    private int mCpuNum = 0;

    public static synchronized ThreadManager instance() {
        if (mThreadManager == null) {
            mThreadManager = new ThreadManager();
        }
        return mThreadManager;
    }

    ThreadManager() {
        mCpuNum = Runtime.getRuntime().availableProcessors();
    }

    public synchronized ExecutorService getExeService() {
        if (mExeService == null || mExeService.isShutdown()) {
            int threadNum = mCpuNum * POOL_SIZE;
            if (threadNum > 3) {
                threadNum = 3;
            }
            mExeService = Executors.newFixedThreadPool(threadNum);
        }
        return mExeService;
    }

实例:

/**
 * 请求百度推荐的应用
 */
public void requestRecommendApp() {
    CXLog.d(TAG, "requestRecommendApp");
    if (!mIsRequesting.get() && mIsExistAppInto) {
        mIsRequesting.set(true);
        mInfoAdapter.updateAppIntoStatus();
        ThreadManager.instance()
                .getExeService()
                .submit(new Runnable() {
                    @Override
                    public void run() {
                        List<ApkModel> apkModelList = mInfoAdapter.getRequestApkList();
                        if (apkModelList != null && apkModelList.size() > 0) {
                            mApkNetworkUtil.requestIntoRecommendApp(apkModelList, getInstalledList());
                            if(CXConfig.DEBUG){
                                CXToastUtil.showToast(mContext,"请求服务器");
                            }
                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if(CXConfig.DEBUG){
                                        CXToastUtil.showToast(mContext,"直接导入");
                                    }

                                    mInfoAdapter.intoReceiveApkList(null);
                                    intoFinish();
                                    mIsExistAppInto = false;
                                    mIsRequesting.set(false);
                                }
                            });
                        }
                    }
                });
    }
}

通过给线程加锁机制。来保证线程安全,以及当前程序当中只有一个x线程池ThreadPool

public class ThreadUtil {
    private static Executor threadPool = Executors.newCachedThreadPool();
    public static void execute(Runnable runnable)
    {
        threadPool.execute(runnable);
    }

}

升级版线程管理类:增加了同步机制

/**
 * 线程管理者。
 *
 * @author peng
 *
 */
public class ThreadManager
{

    private static ThreadPool threadPool; // 单列的线程池对象。

    /**
     * 单列,线程安全
     * 获取一个线程池对象
     * @return
     */
    public static ThreadPool getThreadPool()
    {
        if (threadPool == null)
        {
            //枷锁
            synchronized (ThreadManager.class)
            {
                if (threadPool == null)
                {
                    //核心线程数,等于处理器个数乘2
                    int corePoolSize = Runtime.getRuntime().availableProcessors()*2;
                    int maximumPoolSize = 10;
                    long keepAliveTime = 0L;
                    threadPool = new ThreadPool(corePoolSize, maximumPoolSize, keepAliveTime);
                }
            }
        }

        return threadPool;
    }

    public static class ThreadPool
    {
        public static ThreadPoolExecutor executor = null;

        private int corePoolSize;
        private int maximumPoolSize;
        private long keepAliveTime = 0; // 限制线程的的最大存活时间

        public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime)
        {
            super();
            this.corePoolSize = corePoolSize;  //核心线程数
            this.maximumPoolSize = maximumPoolSize; //最大线程 ,当核心线程用完时。决定是否开启最大线程
            this.keepAliveTime = keepAliveTime;  //线程排队时间,
        }

        /**
         * 线程池:就是把一堆线程放在一起来管理。 1.通过一定的管理机制。来处理线程额执行顺序 2.管理最多可以同时执行的线程数。
         * 3.其他线程通过队列的形式,也就是排队的形式来管理线程的并发数。
         *
         * @param runnable
         */
        public void execute(Runnable runnable)
        {
            if (runnable == null)
            {
                return;
            }

            if (executor == null)
            {

                executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
                        TimeUnit.MILLISECONDS,// 时间单位
                        new LinkedBlockingQueue<Runnable>(),// 线程队列
                        Executors.defaultThreadFactory(),//线程工厂
                        new AbortPolicy());
            }
            // 给线程池里面添加一个线程
            executor.execute(runnable);
        }

    }
}

 Profile GPU Rendering : M Update

  • 从 Android M 系统开始,系统更新了 GPU Profiling 的工具来帮助我们定位 UI 的渲染性能问题。早期的 CPU Profiling 工具只能粗略的显示出 Process,Execute,Update 三大步骤的时间耗费情况。