- okhttp 同步/异步 请求都会在Dispatcher中管理其状态。
- Dispatcher内部维护了一个线程池,用于执行请求call
- Dispatcher维护请求的状态(维护任务队列)
一、Dispatcher 维护的队列
/** Ready async calls in the order they'll be run. */
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();// 准备(就绪)状态的异步队列
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();//运行状态的异步队列
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();//运行状态的同步队列
异步请求,维护了两个队列readyAsyncCalls 和 runningAsyncCalls
二、Dispatcher 维护的线程池
/** Executes calls. Created lazily. */
private @Nullable ExecutorService 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;
}
三、Dispatcher 关键方法分析
1,在执行异步请求的时候,会调用到Dispatcher.enqueue(AsyncCall call)
方法
synchronized void enqueue(AsyncCall call) {
//运行队列数量 < 最大数量 并且 host 也要小于最大数量
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);//在执行的时候,就直接将Call添加到运行队列中
executorService().execute(call);//线程池,执行call
} else {
readyAsyncCalls.add(call);//如果不满足,就加入到准备(缓冲)队列中
}
}
2,异步or同步,执行到最后,都会调用Dispatcher.finished(Deque<T> calls, T call, boolean promoteCalls)
方法;
异步 promoteCalls =true;
同步 promoteCalls =false;
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//先将该请求,从calls 中删除
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
if (promoteCalls) promoteCalls(); //异步,会进入到该方法中
runningCallsCount = runningCallsCount();//重新计算一下,运行的count
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
//----------------------分割线--------------------------
public synchronized int runningCallsCount() {
//该方法,就是获取正在执行call的总数量(异步+同步队列的size)
return runningAsyncCalls.size() + runningSyncCalls.size();
}
3,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();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();//条件满足,将call从准备队列中删除
runningAsyncCalls.add(call);//将call 添加到 运行队列 中
executorService().execute(call);//线程池执行
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
网友评论