进程:
每个app运行时前首先创建一个进程,该进程是由Zygote fork出来的,用于承载App上运行的各种Activity/Service等组件。
进程对于上层应用来说是完全透明的,这也是google有意为之,让App程序都是运行在Android Runtime。大多数情况一个App就运行在一个进程中,除非在AndroidManifest.xml中配置Android:process属性,或通过native代码fork进程。
线程:
线程对应用来说非常常见,比如每次new Thread().start都会创建一个新的线程。该线程与App所在进程之间资源共享,从Linux角度来说进程与线程除了是否共享资源外,并没有本质的区别,都是一个task_struct结构体,在CPU看来进程或线程无非就是一段可执行的代码,CPU采用CFS调度算法,保证每个task都尽可能公平的享有CPU时间片。
一、关于线程池
Android中的线程池的概念来源于Java中的Executor,它们的使用基本是一致的。Executor是一个接口,真正的线程池的实现为ThreadPoolExecutor。ThreadPoolExecutor提供了一系列参数来配置线程池,Android中常用的几种线程池都是通过对ThreadPoolExecutor进行不同配置来实现的。
ThreadPoolExecutor 构造方法
ThreadPoolExecutor 有多个重载方法,但最终都调用了这个构造方法:
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
corePoolSize: 线程池中核心线程的数量。
maximumPoolSize: 线程池中最大线程数量。
keepAliveTime: 非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长。 unit: keepAliveTime这个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等。 workQueue: 线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的。 threadFactory: 为线程池提供创建新线程的功能,这个我们一般使用默认即可。 handler: 拒绝策略,当线程无法执行新任务时(一般是由于线程池中的线程数量已经达到最大数或者线程池关闭导致的),默认情况下,当线程池无法处理新线程时,会抛出一个RejectedExecutionException。
两个执行的方法
ThreadPoolExecutor有两个方法可以供我们执行,分别是submit()和execute(),我们先来看看这两个方法到底有什么差异
execute()方法源码:
if (command == null)
throw new NullPointerException();
//获得当前线程的生命周期对应的二进制状态码
int c = ctl.get();
//判断当前线程数量是否小于核心线程数量,如果小于就直接创建核心线程执行任务,创建成功直接跳出,失败则接着往下走.
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//判断线程池是否为RUNNING状态,并且将任务添加至队列