「阿里巴巴 Android 开发手册」中第 5.3 节对新建线程做了如下强制性要求:
新建线程时,必须通过线程池提供(AsyncTask 或者 ThreadPoolExecutor 或者其他形式自定义的线程池),不允许在应用中自行显式创建线程。
并对此做了如下的说明:
使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。另外创建匿名线程不便于后续的资源使用分析,对性能分析等会造成困扰。
嗯,有理有据,让人信服。接下来将介绍 Thread Pools, Thread Pool Executors 以及它们在 Android 中的使用。
先欣赏一张美丽的图片:
Thread Pool
一个线程池(Thread Pool)管理着一些工作线程(work threads)(具体的数字取决于它的实现方式)。
任务队列(Task Queue)中存储着一些等待着被线程池中的空闲线程执行的任务,这些任务被生产者(producers)添加到队列中,线程池中的工作线程(work threads)充当消费者(consumers)。一旦线程池中有空闲线程准备好执行新的后台任务,它们便会执行(consuming)队列中的任务。
ThreadPoolExecutor
ThreadPoolExecutor 使用线程池中的一个线程去执行给定的 task。
上面是 ThreadPoolExecutor 构造函数中的几个重要参数, 这些参数有什么含义?
- corePoolSize:保留在线程池中的最小线程数,最初在线程池中只有 0 个线程,随着任务被添加到队列中,新线程便会被创建。规则:假设线程池中存在空闲的线程,但是池中线程数小于 corePoolSize,那么将会继续创建新的线程。
- maximumPoolSize:线程池中允许存在的最大线程数,如果 maximumPoolSize 大于 corePoolSize,并且当前池中的线程数大于等于 corePoolSize,那么只有当任务队列已满时才会创建新的线程。
- keepAliveTime:当池中线程的数量大于 core 数时,多余的空闲线程如果在该参数指定的时间内没有等待到一个新的任务,那么它们将会死掉。
- unit:参数 keepAliveTime 的单位。
- workQueue:上面提到的任务队列(task queue),它必须是一个 BlockingQueue,并且只能存储 runnable tasks。
为什么要在 Android 中使用 ThreadPoolExecutor
- ThreadPoolExecutor 是一个强大的任务执行框架,它支持任务添加、取消任务、给任务声明优先级等操作。
- ThreadPoolExecutor 减少了与线程创建相关的开销,因为它在其线程池中管理了一定数量的线程。
在 Android 中使用 ThreadPoolExecutor
首先创建 PriorityThreadFactory(将作为 ThreadPoolExecutor 的一个参数):
|
|
创建 MainThreadExecutor(用于执行主线程中的 tasks):
|
|
创建 DefaultExecutorSupplier(构建、管理不同的 ThreadPoolExecutor )
|
|
PS:corePoolSize 和 maximumPoolSize 请根据自己的时间需求进行设置。
现在,在你的代码中使用它吧!
|
|
通过这种方式,我们可以为网络任务, I/O 操作,耗时的后台任务等创建不同的线程池。enjoy it.
如何取消一个任务
为了取消一个任务,应该使用 submit 方法而不是 execute,它将返回一个 future 对象,使用该返回值可以取消任务。
|
|
全文完
感谢阅读