線程池
Dispatcher#executorService()
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
OkHttp實(shí)現(xiàn)的是無邊界限制的線程池。
參數(shù)解析:
- 0: 核心線程數(shù)。即使空閑也會被保留的線程數(shù)。這里設(shè)置為0,說明沒有被保留的線程,所有空閑的線程都會被終止。
- Integer.MAX_VALUE:線程池可以容納最大線程數(shù)量。Integer.MAX_VALUE是非常大的一個(gè)數(shù),可以理解為OkHttp隨時(shí)可以創(chuàng)建新的線程來滿足需要。可以保證網(wǎng)絡(luò)的I/O任務(wù)有線程來處理,不被阻塞。
- 60, TimeUnit.SECONDS:空閑線程被終止的等待時(shí)間,這里設(shè)置為60秒。
- new SynchronousQueue<Runnable>():阻塞隊(duì)列。SynchronousQueue是這樣 一種阻塞隊(duì)列,其中每個(gè) put 必須等待一個(gè) take,反之亦然。
- Util.threadFactory("OkHttp Dispatcher", false):用來創(chuàng)建線程的線程工廠。
同步請求流程
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
/*
Dispatcher.executed 方法 執(zhí)行入隊(duì)操作
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
*/
client.dispatcher().executed(this);
//進(jìn)入攔截器鏈流程,然后進(jìn)行請求,獲取Response
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
eventListener.callEnd(this, null);
return result;
} catch (IOException e) {
eventListener.callEnd(this, e);
throw e;
} finally {
/*
Dispatcher.finished方法 做的是出隊(duì)操作
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
*/
client.dispatcher().finished(this);
}
}
同步請求總結(jié)
直接進(jìn)入攔截器鏈流程進(jìn)行請求,獲取Response
異步調(diào)用流程
異步調(diào)用用的是 AsyncCall,AsyncCall是RealCall類的內(nèi)部類
- 調(diào)用 RealCall#enqueue 方法
//關(guān)鍵代碼 非源碼
@Override public void enqueue(Callback responseCallback) {
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
- 調(diào)用 Dispatcher#enqueue 方法
synchronized void enqueue(AsyncCall call) {
//入隊(duì)條件:當(dāng)前正在運(yùn)行的AsyncCall < maxRequests(64) && 同一個(gè)Host對應(yīng)的AsyncCall < maxRequestsPerHost(5)
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//入隊(duì)
runningAsyncCalls.add(call);
//將該call 加入線程池執(zhí)行 進(jìn)行網(wǎng)絡(luò)請求的過程基本與同步請求類似
executorService().execute(call);
} else {
//不滿足條件 則加入等待隊(duì)列
readyAsyncCalls.add(call);
}
}
readyAsyncCalls 被恢復(fù)到runningAsyncCalls 的過程
Dispatcher#promoteCalls方法
private void promoteCalls() {
//當(dāng)前正在執(zhí)行的線程超限 return
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
//readyAsyncCalls 為空 return
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
//同一個(gè)Host對應(yīng)的AsyncCall < maxRequestsPerHost(5)
if (runningCallsForHost(call) < maxRequestsPerHost) {
//從readyAsyncCalls中移除
i.remove();
//將該 call 加入到runningAsyncCalls中
runningAsyncCalls.add(call);
//將該call 加入線程池執(zhí)行
executorService().execute(call);
}
//如果runningAsyncCalls滿了就return 否則繼續(xù)循環(huán)
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
Dispatcher#promoteCalls方法 觸發(fā)的時(shí)機(jī)
1.Dispatcher#setMaxRequestsPerHost 被調(diào)用時(shí) 即每個(gè)host對應(yīng)的最大請求數(shù)改變時(shí)
2.Dispatcher#setMaxRequests 被調(diào)用時(shí) 即 同時(shí)進(jìn)行的最大請求數(shù)改變時(shí)
3.Dispatcher#finished 被調(diào)用時(shí) 即一條請求結(jié)束,執(zhí)行了finish()的出隊(duì)操作時(shí)
異步請求總結(jié)
如果滿足入隊(duì)條件,則加入到線程池中進(jìn)行請求。否則會加入到等待隊(duì)列中進(jìn)行等待,等待隊(duì)列中的請求在某些條件被觸發(fā)時(shí)會被移入到正在請求隊(duì)列,并加入到線程池進(jìn)行執(zhí)行。