美文网首页okhttp
okhttp调度器:dispatcher、AsyncCall、p

okhttp调度器:dispatcher、AsyncCall、p

作者: _爱笑的eyes | 来源:发表于2019-06-02 20:45 被阅读0次

    在okhttp中不管是发送同步请求也好,异步请求也好都是会在dispatcher调度器中去管理我们请求的状态。

    dispatcher作用有两条:

    1.维护请求状态

    2.在维护请求状态的前提下又会维护线程池来进行同步请求和异步请求的操作.

    接下来分析一下dispatcher的源码:

    dispatcher内部维护了三个队列。第一个是异步的等待队列,第二个是异步的执行队列,第三个是同步的执行队列。dispatcher使用了两个队列来执行异步请求,为什么异步需要两个,同步只需要一个呢?我们可以把异步的两个队列看成是生产者和消费者的模型,而dispatcher就是生产者,我们知道默认主线程是executedService,把它理解成消费者,从生产者队列dispatcher他会消费AsyncCall这个Runnable,所以说整个流程就非常清晰了。

    回顾一下源码:

    这是异步请求enqueue方法,在这个方法内部是通过dispatcher来进行实际请求的分发的。

    跟进这个enqueue:

    当前的最大请求数是否在允许范围内以及最大的主机请求数是否在范围内,如果是的话,他就会将这个请求扔到异步请求队列当中去执行,然后他会开启相应的线程进行网络请求;那么当他不符合上述条件的时候,就会把这个请求直接扔到异步等待队列当中,等待到什么时候?等待到之前异步队列当中有空余的线程,这时候就会从异步等待队列中去获取想要执行的网络请求。

    跳到AsyncCall,看一下execute这个方法:

    我们知道当一个请求他的call对象执行完毕之后,他会从他的正在执行队列当中去移除这个线程,异步请求队列和异步等待队列是这种情况。那么通过什么来执行的呢?他在finally代码块中会执行一个finished方法,这个finished方法不管你的callback失败也好成功也好都会回调。 

    接下俩看一下finished方法:

    finished内部调用了三个参数的实现。跟进一下:

    这是他的具体实现。他会调用promoteCalls这个方法,这个方法其实就是根据我们正在执行队列的数量,然后会对我们请求的队列的数量进行调整。看一下这个方法是怎么做的:

    首先会判断我们当前正在运行的异步请求的数量是否允许超过他的最大数量,如果操作了就返回了就不要再做其他操作了。

    如果还能进行异步请求,就表示我们这个空闲还有余额的话他会直接返回。

    接着会循环遍历这个等待的执行队列。

    然后会通过next迭代器去获取到AsyncCall实例。

    接着会判断所有的运行的主机是否小于最大的限制,这是一个最大的前提条件。将call从等待队列中移到正在执行的请求队列当中,先移除,然后再把它添加到正在执行的异步请求队列当中。然后会开启一个线程池去执行我们的请求。

    promoteCalls和enqueue方法是一样的,他也是需要去判断maxRequest和maxRequestsPerHost这两个值的约束去执行等待任务中的操作。那么我们okhttp 的disptcher这个调度器默认情况下会给每一个域名快速响应的请求数量,但是还是限制了每一个域名的并发数和总体的并发数。

    线程池做的仅仅是一个缓存的功能,而具体的调度策略还是需要disptcher。而disptcher根据我们不同的应用场景然后自己去配置。关于disptcher就到这里了。

    相关文章

      网友评论

        本文标题:okhttp调度器:dispatcher、AsyncCall、p

        本文链接:https://www.haomeiwen.com/subject/dmqfxctx.html