介紹
Dispatcher對應(yīng)于應(yīng)用層悠栓,通過Dispatcher實現(xiàn)線程的復(fù)用
源碼分析
重點分析executorService()
,finished
惫周,promoteCalls()
executorService()
//executorService是否為空尘惧,可以自定義線程池
if (executorService == null) {
//構(gòu)建一個最少為0,最多無限制闯两,空閑存活時間為60秒褥伴,
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
//無緩沖隊列,線程工廠名為OkHttp Dispatcher
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
內(nèi)置的executorService是一個無緩沖漾狼,先進先出的線程池重慢,可以適應(yīng)于一般的網(wǎng)絡(luò)請求,如果是其他有一定要求的請求逊躁,比如列表圖片加載(有優(yōu)先級)似踱,可能就不太適用了。
finished
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//開始下一個異步線程
if (promoteCalls) promoteCalls();
//統(tǒng)計運行中線程
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
//回調(diào)空閑通知線程稽煤,需先自定義
idleCallback.run();
}
}
通過finished方法來主動控制線程的調(diào)度核芽。
promoteCalls
private void promoteCalls() {
//線程阻塞
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
//判斷Host相同的Request已滿
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
//可能添加線程到滿
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
擴展
Dispatcher向我們展示了怎樣創(chuàng)建一個高并發(fā),底阻塞酵熙,主動調(diào)度的線程池轧简,想要了解更多的線程創(chuàng)建優(yōu)化,建議閱讀《Effectivie Java》并發(fā)章節(jié)