全面深入OkHttp源碼(上)

前言


節(jié)前想著豐富下假期购对,在慕**上花了幾百大洋買了個(gè)課程啡浊,結(jié)果三觀都掉沒(méi)了觅够,雖然現(xiàn)在知識(shí)付費(fèi)了,但這tama也叫高級(jí)課程巷嚣!為了省錢喘先,最直接的辦法就是自己干,當(dāng)然我是指學(xué)習(xí)方面廷粒。

一般而言懂得如何使用窘拯,此人可以認(rèn)定為初級(jí)红且;懂得內(nèi)部邏輯,熟悉流程間銜接涤姊,能夠在框架提供的框框內(nèi)玩耍API暇番,世俗認(rèn)定為此人中高級(jí)、已經(jīng)很不錯(cuò)了思喊;但我認(rèn)為還不夠壁酬。

本著不懂就查,不懂就深追的精神:蘅巍舆乔!此文不同于其他講解(介紹下如何使用、基本的源碼流程剂公、責(zé)任鏈和幾大攔截器希俩,這也是現(xiàn)狀),我劍走偏鋒纲辽,不是流程上的講解颜武,而是深入研讀每一步的源碼了解作者為何及意圖,這也意味著你必需要知道OkHttp淺層的知識(shí)文兑,否則看起來(lái)會(huì)很累盒刚,文章采用CPU響應(yīng)中斷保護(hù)現(xiàn)場(chǎng)的模式書寫,以免思路混亂绿贞,同時(shí)文章也會(huì)異常的長(zhǎng)長(zhǎng)長(zhǎng)因块。。籍铁。涡上。

雖然與現(xiàn)在大環(huán)境相逆,但我深信:知其然拒名,要知其所以然吩愧,這才是真正的工程師,而不是碼農(nóng)增显。

干貨總結(jié)


由于文章太長(zhǎng)雁佳、內(nèi)容太多,相信大多數(shù)人不可能全部讀完同云,因此總結(jié)放在前面糖权,希望能夠提起興趣讀完全文。

  • 接口適配器模式
  • StrictMode之CloseGuard
  • 雙端隊(duì)列的概念及環(huán)形隊(duì)列的操作


    200
300

    /* 4XX: client error */

    /**
     * HTTP Status-Code 400: Bad Request.
     */
    public static final int HTTP_BAD_REQUEST = 400;

    /**
     * HTTP Status-Code 401: Unauthorized.
     */
    public static final int HTTP_UNAUTHORIZED = 401;

    /**
     * HTTP Status-Code 402: Payment Required.
     */
    public static final int HTTP_PAYMENT_REQUIRED = 402;

    /**
     * HTTP Status-Code 403: Forbidden.
     */
    public static final int HTTP_FORBIDDEN = 403;

    /**
     * HTTP Status-Code 404: Not Found.
     */
    public static final int HTTP_NOT_FOUND = 404;

    /**
     * HTTP Status-Code 405: Method Not Allowed.
     */
    public static final int HTTP_BAD_METHOD = 405;

    /**
     * HTTP Status-Code 406: Not Acceptable.
     */
    public static final int HTTP_NOT_ACCEPTABLE = 406;

    /**
     * HTTP Status-Code 407: Proxy Authentication Required.
     */
    public static final int HTTP_PROXY_AUTH = 407;

    /**
     * HTTP Status-Code 408: Request Time-Out.
     */
    public static final int HTTP_CLIENT_TIMEOUT = 408;

    /**
     * HTTP Status-Code 409: Conflict.
     */
    public static final int HTTP_CONFLICT = 409;

    /**
     * HTTP Status-Code 410: Gone.
     */
    public static final int HTTP_GONE = 410;

    /**
     * HTTP Status-Code 411: Length Required.
     */
    public static final int HTTP_LENGTH_REQUIRED = 411;

    /**
     * HTTP Status-Code 412: Precondition Failed.
     */
    public static final int HTTP_PRECON_FAILED = 412;

    /**
     * HTTP Status-Code 413: Request Entity Too Large.
     */
    public static final int HTTP_ENTITY_TOO_LARGE = 413;

    /**
     * HTTP Status-Code 414: Request-URI Too Large.
     */
    public static final int HTTP_REQ_TOO_LONG = 414;

    /**
     * HTTP Status-Code 415: Unsupported Media Type.
     */
    public static final int HTTP_UNSUPPORTED_TYPE = 415;
image.png

正文


以下內(nèi)容基于OkHttp3.11.0版本

OkHttp的所有操作炸站,都在當(dāng)前線程星澳,包括結(jié)果回調(diào),這也意味著使用時(shí)必須為其開(kāi)單獨(dú)的子線程旱易,否則OkHttp內(nèi)部檢查線程時(shí)就會(huì)報(bào)錯(cuò)禁偎。

OkHttpClient通過(guò)構(gòu)建者模式創(chuàng)建實(shí)例腿堤,初始化參數(shù),項(xiàng)目中可以使用單例如暖,如果是多后臺(tái)項(xiàng)目需要清楚內(nèi)部參數(shù)設(shè)置笆檀,看完全文后會(huì)清楚原因。

Request同理創(chuàng)建實(shí)例盒至,初始化參數(shù)误债。并作為參數(shù)初始化接口Call

這里可見(jiàn),Call的實(shí)現(xiàn)類為RealCall妄迁,且持有OkHttpClient實(shí)例對(duì)象。

經(jīng)由靜態(tài)方法李命,進(jìn)入構(gòu)造方法給變量賦值登淘。

分支開(kāi)始EventListener,保存RealCall位置

為什么非要經(jīng)過(guò)靜態(tài)方法呢封字?給每一個(gè)Call對(duì)象的eventListener賦值為
經(jīng)okHttpClient實(shí)例對(duì)象eventListenerFactory創(chuàng)建的EventListener黔州。

OkHttpClient

EventListener.Factory來(lái)自Builder

如果Builder沒(méi)有主動(dòng)設(shè)置過(guò),則默認(rèn)生成阔籽。

EventListener.Factory接口根據(jù)傳入的Call生成EventListener

EventListener是什么有什么用流妻?

通過(guò)類結(jié)構(gòu),可以看出EventListener是一個(gè)抽象類笆制,采用適配器模式(若定義為接口绅这,則必須實(shí)現(xiàn)全部方法,又稱接口適配器模式)默認(rèn)每個(gè)方法都是空實(shí)現(xiàn)在辆,繼承者根據(jù)需要實(shí)現(xiàn)相應(yīng)方法证薇。方法名也很好理解,結(jié)果表明:這就是是請(qǐng)求生命周期的回調(diào)匆篓,在請(qǐng)求的不同時(shí)期會(huì)回調(diào)相應(yīng)的方法浑度。

那Call中的EventListener對(duì)象是哪里實(shí)現(xiàn)的?

一步步鸦概,通過(guò)Builder初始化默認(rèn)eventListenerFactory箩张,再傳遞到okHttpClient的eventListenerFactory,最終由eventListenerFactory創(chuàng)建EventListener窗市。

哪里跋瓤丁?沒(méi)看見(jiàn)谨设!這里確實(shí)繞了幾個(gè)彎熟掂,第三、四張圖是關(guān)鍵扎拣。

第四張圖靜態(tài)方法生成EventListenerFactory赴肚,但非常簡(jiǎn)單素跺,傳入的參數(shù)是EventListener,什么都沒(méi)做就返回出去了誉券,表明實(shí)際的eventListener對(duì)象是外部初始化后傳入的指厌。

回來(lái)看第三張圖,傳入的eventListener對(duì)象是什么踊跟?EventListener.NONE踩验,又回去

eventListener對(duì)象為默認(rèn)的EventListener類內(nèi)部靜態(tài)變量,且各個(gè)生命周期的回調(diào)并沒(méi)有重寫商玫,意味著生命周期回調(diào)還是空實(shí)現(xiàn)箕憾。

這里就需要我們手動(dòng)繼承EventListener實(shí)現(xiàn)自己的生命周期監(jiān)聽(tīng)類,并實(shí)現(xiàn)

EventListener.Factory接口拳昌,重寫create返回自己的生命周期監(jiān)聽(tīng)類袭异,賦值給OkHttpClient.Builder

這樣下來(lái),經(jīng)由此okHttpClient對(duì)象的Call炬藤,在相應(yīng)的生命周期就會(huì)回調(diào)到自己的生命周期監(jiān)聽(tīng)類內(nèi)御铃。

雖然代碼繞來(lái)繞去,但更能夠理解作者的意圖沈矿,每個(gè)okHttpClient對(duì)象內(nèi)不直接賦值或生成EventListener上真,而是存儲(chǔ)eventListenerFactory工廠,讓具體的EventListener由具體的eventListenerFactory生成羹膳,降低了okHttpClient對(duì)象與eventListener對(duì)象的耦合睡互。

分支結(jié)束EventListener,讀取RealCall位置

RealCall的構(gòu)造方法內(nèi)還賦值了retryAndFollowUpInterceptor變量溜徙,這是攔截器的起點(diǎn)(下面講)湃缎。

Call對(duì)象初始化完成,其實(shí)就是基本的變量初始化蠢壹。

執(zhí)行execute方法嗓违,在其實(shí)現(xiàn)類RealCall內(nèi)

每個(gè)Call對(duì)象只能被執(zhí)行一次,有變量executed來(lái)記錄自己是否被執(zhí)行過(guò)图贸,這里加鎖為了防止多線程間線程安全蹂季,因?yàn)槊總€(gè)請(qǐng)求都會(huì)放到池子pool內(nèi)(后面講)。

分支開(kāi)始StackTrace疏日,保存RealCall位置

execute內(nèi)執(zhí)行captureCallStackTrace偿洁,譯為"開(kāi)啟Call的棧跟蹤"。

Platform類如其意"平臺(tái)"沟优,注意有Android的Logger打印日志類變量涕滋,返回的PLATFORM來(lái)自findPlatform。

注釋也寫了挠阁,通過(guò)運(yùn)行環(huán)境匹配合適的Platform宾肺,這里列舉了幾個(gè)平臺(tái)溯饵,除了android其他的都不認(rèn)識(shí)。

如果運(yùn)行環(huán)境平臺(tái)都不符合锨用,則new Platform();

方法getStackTraceForCloseable返回的是Throwable

若符合android平臺(tái)丰刊,通過(guò)反射獲取一些證書、Session等網(wǎng)絡(luò)相關(guān)的類增拥。當(dāng)Platform支持此功能時(shí)啄巧,便會(huì)反射invoke相關(guān)功能。

AndroidPlatform

返回AndroidPlatform掌栅,其繼承自Platform

android平臺(tái)下getStackTraceForCloseable被重寫

這里有個(gè)內(nèi)部類CloseGuard秩仆,其實(shí)這個(gè)類在android源碼dalvik.system.CloseGuard包下,注釋中也有提到猾封,這里只是利用反射逗概,封裝了原CloseGuard的方法。

分支開(kāi)始CloseGuard忘衍,保存StackTrace位置

先看看源碼中的CloseGuard類

想多學(xué)習(xí)的也可以看看 http://duanqz.github.io/2015-11-04-StrictMode-Analysis#All

源碼取自android7.0路徑看圖

注釋中解釋了此類的作用及如何使用,我再?gòu)?fù)述一遍卿城。

CloseGuard類用來(lái)記錄對(duì)象是否被關(guān)閉枚钓,某些情況下如果對(duì)象不關(guān)閉的話就會(huì)造成內(nèi)存泄露或其他問(wèn)題,由于CloseGuard類是源碼級(jí)別的類瑟押,很多源碼中判斷對(duì)象是否關(guān)閉都有用到它如InputStream搀捷,可以看看引用的文章。

CloseGuard類使用也很簡(jiǎn)單多望,如例子嫩舟,在使用對(duì)象Foo類中增加變量guard,實(shí)例化Foo對(duì)象時(shí)調(diào)用guard的open方法怀偷,表示對(duì)象開(kāi)啟在被使用家厌,對(duì)象關(guān)閉調(diào)用cleanup,此時(shí)guard調(diào)用close椎工,表明對(duì)象關(guān)閉不再使用饭于。此時(shí)JVM便會(huì)GC此對(duì)象調(diào)用其finalize方法,如果對(duì)象不被使用且沒(méi)有關(guān)閉調(diào)用cleanup(即內(nèi)存泄露)维蒙,GC時(shí)便會(huì)發(fā)現(xiàn)guard掰吕,并警告調(diào)用warnIfOpen。

整體思路就是這樣颅痊,看看源碼的實(shí)現(xiàn)殖熟。

注釋寫的很好,很明白斑响。

CloseGuard類為final菱属,在JVM方法區(qū)運(yùn)行時(shí)常量池中存在NOOP對(duì)象钳榨,當(dāng)CloseGuard功能不使用時(shí),可避免浪費(fèi)內(nèi)存生成對(duì)象照皆。

CloseGuard功能默認(rèn)是打開(kāi)的重绷,android在啟動(dòng)的時(shí)候關(guān)閉了此功能,注釋中也有提到膜毁。

何為關(guān)閉昭卓?功能開(kāi)啟情況下一個(gè)對(duì)象對(duì)應(yīng)一個(gè)CloseGuard對(duì)象,關(guān)閉情況下瘟滨,所有對(duì)象對(duì)應(yīng)一個(gè)CloseGuard對(duì)象NOOP候醒,即起不到監(jiān)控對(duì)象是開(kāi)啟還是關(guān)閉的狀態(tài)。

get方法直接返回自己或?qū)嵗约?/p>

open方法則初始化了Throwable的allocationSite對(duì)象杂瘸,針對(duì)不同的對(duì)象傳入不同的closer信息倒淫,可以加速問(wèn)題的排查

close方法置空了allocationSite對(duì)象

warnIfOpen方法在發(fā)現(xiàn)功能開(kāi)啟且對(duì)象未關(guān)閉時(shí),便會(huì)報(bào)異常信息

而報(bào)異常信息的對(duì)象是系統(tǒng)級(jí)別

分支結(jié)束CloseGuard败玉,讀取StackTrace位置

CloseGuard通過(guò)反射取得源類的Method作為自己的變量敌土,對(duì)象調(diào)用方法時(shí),再利用反射invoke源類中相應(yīng)的方法运翼,達(dá)到對(duì)應(yīng)的功能

getStackTraceForCloseable方法調(diào)用返回的是源CloseGuard對(duì)象

源CloseGuard對(duì)象

RealCall

又被賦值給責(zé)任鏈的第一環(huán)RetryAndFollowUpInterceptor攔截器中返干,此時(shí)的對(duì)象關(guān)系為:RealCall對(duì)象持有RetryAndFollowUpInterceptor對(duì)象,RetryAndFollowUpInterceptor對(duì)象持有CloseGuard對(duì)象血淌。簡(jiǎn)言之:一個(gè)Call對(duì)象對(duì)應(yīng)一個(gè)CloseGuard對(duì)象矩欠,當(dāng)Call對(duì)象沒(méi)有被close時(shí)便會(huì)報(bào)異常。

那這個(gè)CloseGuard對(duì)象何時(shí)被close呢悠夯?答案是沒(méi)有癌淮,因?yàn)橛谐刈拥年P(guān)系所有的Call都在池子內(nèi),當(dāng)Call真正被回收清除的時(shí)候就會(huì)通過(guò)CloseGuard對(duì)象log下沦补。

RetryAndFollowUpInterceptor

CloseGuard對(duì)象賦值給RetryAndFollowUpInterceptor對(duì)象

RetryAndFollowUpInterceptor

RetryAndFollowUpInterceptor對(duì)象轉(zhuǎn)手有將它賦值給StreamAllocation對(duì)象(后面講)

StreamAllocation

StreamAllocation對(duì)象轉(zhuǎn)手有將它賦值給StreamAllocationReference它自己的弱引用

當(dāng)池子需要清理了

ConnectionPool

便會(huì)取出之前的CloseGuard對(duì)象

log一下通知此連接已關(guān)閉乳蓄,但并非真關(guān)閉,只是此次的連接請(qǐng)求關(guān)閉了夕膀,連接本身還留著執(zhí)行下次的請(qǐng)求栓袖,這是pool的功能。

如果CloseGuard對(duì)象沒(méi)有成功log店诗,便會(huì)調(diào)用android中的Log類裹刮。

到此就是整個(gè)Call連接的路徑追蹤,從創(chuàng)建Call到連接流關(guān)閉庞瘸,Platformge根據(jù)平臺(tái)的不同捧弃,以不同的方式打印追蹤C(jī)all連接流的關(guān)閉事件。

分支結(jié)束StackTrace,讀取RealCall位置

eventListener生命周期回調(diào)callStart

緊接著httpClient對(duì)象調(diào)用dispatcher執(zhí)行call對(duì)象

OkHttpClient

dispatcher對(duì)象在httpClient通過(guò)builder創(chuàng)建時(shí)默認(rèn)生成

OkHttpClient

Dispatcher為異步請(qǐng)求執(zhí)行策略违霞,且為final類不允許繼承

有可能官方后面會(huì)有擴(kuò)充嘴办,通過(guò)開(kāi)放繼承或?qū)崿F(xiàn)接口以用來(lái)個(gè)性化定制。目前版本买鸽,此類主要針對(duì)異步請(qǐng)求涧郊,對(duì)同步請(qǐng)求沒(méi)影響僅做計(jì)數(shù)功能

Dispatcher中幾個(gè)重要的變量,從上至下依次(其實(shí)變量名起的很明白)

  • 最大請(qǐng)求數(shù)
  • 每臺(tái)主機(jī)最大請(qǐng)求數(shù)
  • Dispatcher空閑時(shí)的回調(diào)
  • 線程池
  • 異步等待隊(duì)列
  • 異步請(qǐng)求隊(duì)列
  • 同步請(qǐng)求隊(duì)列

分支開(kāi)始Deque眼五,保存RealCall位置

什么是Deque妆艘?與Queue有什么關(guān)系?Queue又是什么看幼?

Queue是數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列批旺,Queue提供了隊(duì)列的基本操作,不同的實(shí)現(xiàn)類有具體的實(shí)現(xiàn)

ArrayDeque

通過(guò)類圖看出诵姜,Deque接口繼承自Queue汽煮,Dispatcher中的對(duì)象為ArrayDeque,它實(shí)現(xiàn)了Deque接口并繼承自AbstractCollection棚唆。

那不是實(shí)現(xiàn)了兩次Collection接口嗎暇赤?

并不是,首先看一下實(shí)現(xiàn)與繼承的區(qū)別:

java是單繼承多實(shí)現(xiàn)宵凌,接口表示具體功能翎卓,實(shí)現(xiàn)接口意味著類具有某功能。繼承為子承父業(yè)摆寄,父類具有的功能,子類同樣具有坯门。實(shí)現(xiàn)為具有某功能微饥,繼承為具有某功能的實(shí)現(xiàn)。

AbstractCollection為抽象類古戴,實(shí)現(xiàn)了Collection聲明的方法欠橘,又將功能合并生成抽象方法;ArrayDeque實(shí)現(xiàn)了Collection接口现恼,表示ArrayDeque類具有Collection接口聲明的功能肃续,功能的具體實(shí)現(xiàn)在父類AbstractCollection中,ArrayDeque只需實(shí)現(xiàn)AbstractCollection類合并功能后的抽象方法叉袍。

簡(jiǎn)言之:ArrayDeque實(shí)現(xiàn)了Collection接口始锚,但具體的實(shí)現(xiàn)在AbstractCollection中。這種設(shè)計(jì)思路值得學(xué)習(xí)

Queue為隊(duì)列提供了隊(duì)尾插入add喳逛、offer功能瞧捌,隊(duì)首移除remove、poll功能,還有偷窺隊(duì)首元素element姐呐、peek功能殿怜,屬于常規(guī)的隊(duì)列操作接口

Deque繼承自Queue,但其增加了隊(duì)列首尾的功能曙砂,使隊(duì)列成為雙端隊(duì)列头谜,即首尾都可插入、移除鸠澈。其還有棧功能柱告,但不在此次介紹范圍內(nèi)。

Deque

ArrayDeque為雙端隊(duì)列實(shí)現(xiàn)的其中一種款侵,簡(jiǎn)單看下源碼:

與大部分集合工具類一樣末荐,具體的數(shù)據(jù)存儲(chǔ)在數(shù)組中,可以看到transient關(guān)鍵字新锈,表明不能夠被序列化甲脏,但其內(nèi)部有writeObject、readObject自己的序列化方式妹笆。

ArrayDeque是一種環(huán)形隊(duì)列(源碼中的head块请、tail指針與圖中的算法不同,此圖僅做參考拳缠,ArrayDeque中tail指針指null)

來(lái)自LeetCode https://leetcode.com/explore/learn/card/queue-stack/

通過(guò)head墩新、tail指針完成整個(gè)隊(duì)列的操作

初始化存儲(chǔ)空間,numElements二進(jìn)制每位或1操作窟坐,使initialCapacity為奇數(shù)海渊,再自加為偶數(shù),保證initialCapacity一定為2的n次方(英文翻譯)哲鸳,正確應(yīng)是:保證initialCapacity一定為偶數(shù)臣疑,只有這樣在后面的求mask時(shí)二進(jìn)制的各位才能都被與操作到。

如果initialCapacity超出最大長(zhǎng)度則分配2^30 elements

雙端隊(duì)列插入操作

ArrayDeque

頭部指針指向位置插入元素

紅框標(biāo)示的位置及為什么ArrayDeque的容量必須為偶數(shù)徙菠,只有偶數(shù)減1讯沈,必為奇數(shù),而奇數(shù)二進(jìn)制位的最后一位必定位1婿奔,這樣與操作才不會(huì)漏位缺狠。

offer的內(nèi)部邏輯與add是一致的,只不過(guò)offer成功會(huì)return true萍摊,不成功就NullPointerException

接著就是擴(kuò)容邏輯

斷言判斷隊(duì)列是否已滿挤茄,保存臨時(shí)變量記錄位置,容量擴(kuò)為原來(lái)的2倍冰木,

將隊(duì)列中head指針右側(cè)的數(shù)組蝇闭,拷貝到新數(shù)組的左端,緊接著拷貝剩余位置起點(diǎn)到tail指針的數(shù)組缴守,最終新數(shù)組左側(cè)填滿,右側(cè)空挖腰。

poll操作不會(huì)拋出異常,而remove不同,會(huì)有NoSuchElementException

為什么說(shuō)tail指null呢练湿?看pollFirst直接取head指針取數(shù)據(jù)猴仑,而pollLast是先計(jì)算tail指針再去取

注意get操作,并沒(méi)有刪除數(shù)據(jù)肥哎,但會(huì)NoSuchElementException

反倒peek不會(huì)

移除第一個(gè)匹配項(xiàng)辽俗,分為從head循環(huán)和tail循環(huán),首次遇到equal項(xiàng)即刪除

所有的數(shù)組集合工具類一樣篡诽,刪除意味著移動(dòng)

check了隊(duì)列的正確性后崖飘,移動(dòng)數(shù)組,分了兩種情況:

  • head在tail前
  • head在tail后

隊(duì)列操作的實(shí)質(zhì)

驗(yàn)證了我之前對(duì)head和tail的解析

分支結(jié)束Deque杈女,讀取RealCall位置

Dispatcher使用隊(duì)列朱浴,正式因?yàn)殛?duì)列的FIFO性質(zhì),符合網(wǎng)絡(luò)請(qǐng)求的場(chǎng)景

dispatcher對(duì)象將call對(duì)象放入同步請(qǐng)求隊(duì)列runningSyncCalls即結(jié)束

然后在請(qǐng)求返回后达椰,調(diào)用dispatcher對(duì)象將call結(jié)束

簡(jiǎn)單的操作翰蠢,將call從隊(duì)列中移除,由于是同步操作所以沒(méi)有觸發(fā)promoteCalls啰劲,并重新計(jì)算此dispatcher(即okHttpclient)中正在運(yùn)行的call總數(shù)

也很easy就是求和梁沧,如果沒(méi)有正在執(zhí)行的請(qǐng)求就執(zhí)行Dispatcher空閑時(shí)的回調(diào)。

現(xiàn)在可能對(duì)Dispatcher的作用產(chǎn)生疑問(wèn)蝇裤,它到底有什么用廷支?提前劇透,OkHttp中有池子的概念即復(fù)用栓辜,這會(huì)導(dǎo)致不同的請(qǐng)求使用同一個(gè)流恋拍,如何正確的識(shí)別請(qǐng)求而對(duì)外屏蔽池子,即是Dispatcher的功能啃憎。我們只管向Dispatcher中加請(qǐng)求,完成了就移除似炎,判斷請(qǐng)求存在與否時(shí)直接使用Dispatcher辛萍,即使請(qǐng)求被復(fù)用到了其他請(qǐng)求,Dispatcher也會(huì)將之前的請(qǐng)求移除羡藐,認(rèn)為是不同的操作贩毕。

除了以上Dispatcher還做了請(qǐng)求量的控制和一些基本Call對(duì)象操作,接下來(lái)異步請(qǐng)求時(shí)會(huì)涉及

Dispatcher的在同步請(qǐng)求時(shí)沒(méi)做多少事情仆嗦,到此就休息了辉阶。那請(qǐng)求的結(jié)果是如何得到的?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谆甜,隨后出現(xiàn)的幾起案子垃僚,更是在濱河造成了極大的恐慌,老刑警劉巖规辱,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谆棺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡罕袋,警方通過(guò)查閱死者的電腦和手機(jī)改淑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浴讯,“玉大人朵夏,你說(shuō)我怎么就攤上這事∮芘Γ” “怎么了仰猖?”我有些...
    開(kāi)封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)掠河。 經(jīng)常有香客問(wèn)我亮元,道長(zhǎng),這世上最難降的妖魔是什么唠摹? 我笑而不...
    開(kāi)封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任爆捞,我火速辦了婚禮,結(jié)果婚禮上勾拉,老公的妹妹穿的比我還像新娘煮甥。我一直安慰自己,他們只是感情好藕赞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布成肘。 她就那樣靜靜地躺著,像睡著了一般斧蜕。 火紅的嫁衣襯著肌膚如雪双霍。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天批销,我揣著相機(jī)與錄音洒闸,去河邊找鬼。 笑死均芽,一個(gè)胖子當(dāng)著我的面吹牛丘逸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掀宋,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼深纲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼仲锄!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起湃鹊,我...
    開(kāi)封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤儒喊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后涛舍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體澄惊,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年富雅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掸驱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡没佑,死狀恐怖毕贼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛤奢,我是刑警寧澤鬼癣,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站啤贩,受9級(jí)特大地震影響待秃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痹屹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一章郁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧志衍,春花似錦暖庄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至春叫,卻和暖如春肩钠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暂殖。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工价匠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人央星。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓霞怀,卻偏偏與公主長(zhǎng)得像惫东,于是被迫代替她去往敵國(guó)和親莉给。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毙石,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容