【安卓开发艺术探索】第11章 线程线程池 笔记

来源:互联网 发布:python opencv pil 编辑:程序博客网 时间:2024/06/06 01:43

写在前面

之前参加过的一些面试中,或多或少有问到类似如下的问题:

  • android中如何创建线程?
  • android有哪些执行耗时任务的方法?
  • android中有哪些异步的方式?

以上的这些问题,实质上其实都是关于线程和线程池的问题,当然还要回答一些比如Async Task和Intent Service的东西。但是当问到第一点时,千万别以为面试官只是单纯地想听你说“继承于Thread来写自己的子类”“用new Thread(Runnable)来构造新的线程再启动”,面试官真正期待的回答一定是想让你也讲讲线程池的用法的。

Thread缺点

每次线程的构造和启动,以及最后执行完的回收都需要消耗宝贵的CPU资源,如果不加以合理的控制,比如要大量显示网络的图片,从而产生大量的thread来下载网络图片时,这样的效率是极其低下的。
所以如果只知道在遇到异步任务的时候上来就用Thread,那只能说offer会与你失之交臂了。

Async Task缺点

参考链接:http://blog.csdn.net/goodlixueyong/article/details/45895997
主要是4个方面,生命周期、内存泄漏、结果丢失、版本不同。值得注意的是Async Task实现是基于线程池的。

线程池的优点

在前面的种种情形下,终于可以开始讲线程池的优势:

  • 重用线程池中的线程,避免了创建、销毁线程时带来的开销。
  • 能有效控制线程池的最大并发数,避免大量线程之间抢占资源导致的拥塞。
  • 能提供一些简单的管理,比如定时执行等。

Android提供的4种线程池均基于ThreadPoolExecutor,构造方法中有如下的参数:

  • int corePoolSize 核心线程的数量
  • int maximumPoolSize 最大线程数量
  • long keepAliveTime 非核心线程的闲置超时时长
  • TimeUnit unit 上述时长的时间单位
  • BlockingQueue<Runnable> workQueue 任务队列
  • ThreadFactory threadFactory 线程工厂,只需要提供一个Thread newThread(Runnable r) 方法即可。

线程池任务分配原则:

  • 如果线程数少于核心线程,则创建核心线程来执行。
  • 如果线程数已经大于或等于核心线程,小于最大线程数量时,优先放到队列里。
  • 队列满的时候,创建新的非核心线程。
  • 非核心线程达到上限,则拒绝接受。调用RejectedExecutionHandlerrejectionExecution方法。

Android中的4种线程池

FixedThreadPool

核心线程数和最大线程数相同且固定,即没有非核心线程,所有多余任务处在排队队列中等待。

CachedThreadPool

线程数量不定且可认为无穷大,只有非核心线程,即所有任务都被分配在新的非核心线程或可重用的非核心线程。没有任务队列。

ScheduledThreadPool

特点是用于执行定时任务,其他特点不太好记,不详述了。

SingleThreadExecutor

特点是只有一个核心线程,保证所有任务按顺序执行,不需要处理线程同步的问题。

补充

除了AsyncTask,Thread,ThreadPool,或者是Handler.post,View.post一个异步Runnable任务,还有一种也是基于Thread的方式,比较方便执行轻量级的周期任务Timer&TimerTask。
但是Timer&TimerTask也有自己不好的地方,当timer.cancel()之后,你想再次恢复所有的任务时就之只能重新new Timer,new TimerTask了,对连TimerTask都要重新创建。。

0 0