【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隊列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章