在之前已经对okhttp的同步和异步请求的流程进行了详细的分析,其中任务调度是由dispatcher来实现的,非常重要,所以这次专门来对它进行一个了解,带着问题去进行探究:
Q1:okhttp如何实现同步异步请求?
发送的同步 / 异步请求都会在dispatcher中管理状态。
Q2:到底什么是dispatcher?
dispatcher的作用为维护请求的状态,并维护一个线程池,用于执行请求。还是用一个图来大体感受一下,这个在之前也看过:
每当有请求来时则会将封装的Call对象通过Dispatcher推送到readyAsyncCalls就绪请求队列中,而Okhttp相对其它的网络请求框架高效在维护了一个线程池,能够更加高效的执行异步请求,下面还是来看一下Dispatcher的源码,先来看一下它里面定义的几个队列,这个在之前也已经看过了,但是由于它非常之重要所以再来温故一下:
Q3:异步请求为什么需要两个队列?
如下:
其实可以把Dispatcher理解成生产者-消费者模型,其Dispatcher为生产者,ExecutorService为消费者,所以此时就需要用二个队列来表示。
从同步异步请求中再来分析dispatcher:
同步请求:
异步请求:
接着来看一下线程池是如何创建的:
那意味着如果来了20个并发请求,线程池中会创建20个线程,当在60s之后则相继关闭无用的线程。
Q4:Call执行完肯定需要在runningAsyncCalls队列中移除这个线程,那么readyAsyncCalls队列中的线程什么时候才会被执行呢?
所以此时就得看一下finished()方法了:
看一下它的具体实现:
其计算也比较简单: