概述
OkHttp 的任务队列在内部维护了一个线程池用于执行具体的网络请求,达到方便高效地进行异步请求的目的。在 OkHttp 内部,这个工作是由 Dispatcher 来完成的。
关于线程池的知识,请参考我的博客
Java 线程池 – 线程池基础
Java 线程池 – ThreadPoolExecutor 源码解析
Java 线程池 – ThreadPoolExecutor 使用攻略
Dispatcher
Dispatcher 主要负责创建线程池以及为任务找到合适的执行线程。
1 | public final class Dispatcher { |
Dispatcher 内部有三个任务队列,去执行同步任务和异步任务。
默认创建的线程池的 corePoolSize 为0,maximumPoolSize 为无限大,意味着线程数量可以无限大。
采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。
keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死。
也就是说,在实际运行中,当收到10个并发请求时,线程池会创建十个线程,当工作完成后,线程池会在60s后相继关闭所有线程。
同步请求
来看一下 RealCall.execute()
方法:
1 | @Override public Response execute() throws IOException { |
1 | synchronized void executed(RealCall call) { |
executed
方法做的事情就是把任务加到正在执行的同步任务队列中去。
1 | void finished(RealCall call) { |
异步请求
来看一下 RealCall.enqueue()
方法:
1 | @Override public void enqueue(Callback responseCallback) { |
Dispatcher.enqueue()
1 | synchronized void enqueue(AsyncCall call) { |
AsyncCall.execute()
方法:
1 | @Override protected void execute() { |
1 | void finished(AsyncCall call) { |