线程池在移动端开发过程中,在提高性能、充分利用GPU方面,有着不错的表现。Executor是个比较庞大的家族,Executor的子孙众多。常用的ThreadPoolExecutor、FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor等。
Executor是只有一个void execute(Runnable command)为实现的方法的接口类,是实现Android并发编程线程池框架的基础。
ExecutorService
先看下ExecutorService类,这个是Executor的二级接口类,也只是个接口。具有有序的关闭池中线程的功能,一定执行,不再接受其他的线程加入。也可以等待所有的都执行完毕,在处理,但比较危险。
盗图(不完整)
从图中看出,ExecutorService接口类是ThreadPoolExecutor和ScheduledExecutor的基础。ForkJoinPool类和ThreadPoolExecutor一样,都是AbstractExecutorService的子类。ForkJoinPool是1.7版本加入进来的。上面的图并没有体现。
1、ForkJoinPool
ForkJoinPool是为了特使的场景而生的,具体看看作者的论文。很强大。
ForkJoinPool采用的分治算法,和归并排序算法类似,就是将任务切割到最小。
2、ThreadPoolExecutor
ThreadPoolExecutor是用的最多的一个线程池,在较多线程开发时,ThreadPoolExecutor控制好线程的可调度资源、并发线程数量。ThreadPoolExecutor的用法,分享个链接。
这里,我不讲如何使用,我想从源码角度分析,线程是如何维护的。
a、列队
既然是池子,那说明里面维护的线程绝不可能永远只有一个,那线程都在哪里?当然就是列队。有PriorityQueue优先级列队、内部含有PriorityQueue(优先级)的DelayQueue延时列队、数组结构的PriorityBlockingQueue优先级阻塞列队、单链表结构的LinkedBlockingQueue无界阻塞列队、数组结构的ArrayBlockingQueue有界阻塞列队,当然,还有LinkedBlockingDeque双向链表阻塞列队。具体使用哪个列队承载线程,视情况而定即可。
这些列队,都实现了迭代器和分割器,因为都是非线程安全的,请善用。由于列队种类过对,这里我不就针对每一个进行分析下,在使用线程池的时候,知道原理以及特性,也是有助于更好使用线程池的。
PriorityQueue:
原理:默认情况下,他是个有默认排序的列队的排序,也可以传入一个Comparable比较器,对列队进行排序。PriorityQueue内部列队,是使用数组承载的。
代码解析:添加元素。
// 添加元素
public boolean add(E e) {
return offer(e);
}
...
// 将元素添加到有序的优先级列队中。
public boolean offer(E e) {
if (e =