
我们在前面的同步异步请求源码分析中经常会到 Dispatcher 类中去调用一些方法。
OkHttp如何实现同步异步请求的呢?
发送的同步/异步的请求都会在 Dispatcher 中管理其状态
到底什么是Dispatcher?
Dispatcher 的作用为维护同步/异步请求的状态,同时它在它的内部维护一个线程池,用于执行相应的请求。
我们去看 Dispatcher 的源码 ===>

上面的源码我们看到很多次了
- runningSyncCalls 正在执行的同步请求队列
- runningAsyncCalls 正在执行的异步请求队列,并且包含了已经取消但没执行完成的异步请求
- readyAsyncCalls 就绪的异步请求队列,当我们整个的异步请求不满足一个条件的是时候,它就会进入到我们就绪的异步请求队列中,来进行缓存,如果当条件在满足了之后,就会把就绪的异步请求队列放到正在执行的异步请求队列中去执行。
- executorService 线程池,这个线程池正是dispatcher中维护了整个异步之间的请求和高效的网路操作
先去同步请求中 Dispatcher 调用的管理
通过同步请求代码流程找到

最后到 dispatcher 中的 executed() 方法和 finished() 方法中去看看


可以看到再同步请求中 dispatcher 就只做了两件事:
1.直接将同步请求加入到正在执行的同步请求队列中(不会像异步请求添加到请求队列会考虑一些情况)
2.将同步请求移除到正在执行的同步请求队列
异步请求中 Dispatcher 调用的管理
通过异步请求代码流程找到

可以知道是到了 dispatcher 的 enqueue() 方法中

同时我们再去看看 dispatcher 中线程池 executorService()的创建方法中看看

这里细细的想了想,dispatcher 就是维护我们的请求队列,在异步中它维护了一个线程池 executorService 用于执行异步的网络请求。当请求满足 enqueue() 方法中 if 的条件的时候,dispatcher就会直接将异步请求放入正在执行的异步请求队列中。并且调用线程池来执行开启任务。 如果不满足就把异步请求放入到缓存的异步请求队列中,等到条件满足再将异步请求放入正在执行的异步请求队列中去。
我们再看最后一个


在异步和同步 中不管请求怎么样都会去执行 dispatcher 中的 finished()方法
我们就去看看 这个方法

最后在异步请求会多调用一个方法 promoteCalls() 我们去看看

这下就明白 为什么只有 异步请求 才会去调用这个调整异步请求队列的方法。
好了,这就是 dispatcher 在 OkHttp 中所做的所有内容。
网友评论