【Android okhttp源码解析 四】任务调度核心类dispatcher解析

okhttp源码解析系列文章:
第一篇:《okhttp框架简单介绍》
https://blog.csdn.net/colinandroid/article/details/79774907
第二篇:《同步请求流程和源码分析》
https://blog.csdn.net/colinandroid/article/details/79774918
第三篇:《异步请求流程和源码分析》
https://blog.csdn.net/colinandroid/article/details/79774932
第四篇:《任务调度核心类dispatcher解析》
https://blog.csdn.net/colinandroid/article/details/79774936
第五篇:《拦截器流程和源码解析》
https://blog.csdn.net/colinandroid/article/details/79706161

okhttp如何实现同步异步请求,这就是由dispatcher来管理的。我们来借助一张图来理解一下dispatcher工作原理
这里写图片描述
每当有网络请求Call时,dispatcher会把这个请求推送到readyAsyncCalls队列中,而okhttp相比其他网络请求框架的高效之处就在于它内部维护了一个线程池,来高效地执行网络请求。我们来看下dispatcher源码。

1. dispatcher维护的三个队列

这里写图片描述

(1)runningAsyncCalls队列

这是正在执行的异步请求队列。从注释来看,它包含了已经取消但没有执行完成的异步请求。

(2)readyAsyncCalls队列

这是就绪状态的异步请求队列。当异步请求不满足某些条件时,就会进入到该队列来进行缓存,如果条件再满足后,就会把这个队列里的请求放到runningAsyncCalls队列。

(3)runningSyncCalls队列

这是正在执行的同步请求队列。
我们来思考一下,同步请求只维护了一个队列,异步请求为什么要维护两个队列?我们这里理解为生产者和消费者模型,我们的分发器Dispatcher对应为生产者,我们的线程池ExecutorService对应为消费者池,所以这里需要两个队列,一个队列存放正在执行的异步请求,一个存放准备继续的异步请求。

2. promoteCalls()方法如何实现?

前文我们介绍了promoteCalls()方法的功能:对异步请求的两个队列进行调度,也就是将runningAsyncCalls队列中执行完的请求移除,接着把readyAsyncCalls队列中优先级最高的请求拿出来放到runningAsyncCalls队列中。我们来看下具体实现:
这里写图片描述
在for循环中会对readyAsyncCalls队列进行遍历,取出里面的请求添加到runningAsyncCalls队列中,直到填满runningAsyncCalls队列。

猜你喜欢

转载自blog.csdn.net/colinandroid/article/details/79774936