看过OKHTTP源码的都会知道,里面有个任务调度Dispatcher
这里分析一下Dispatcher源码:
public final class Dispatcher {
private int maxRequests = 64;//最大请求数
private int maxRequestsPerHost = 5;//最大主机数
private @Nullable Runnable idleCallback;//空闲回调
private @Nullable ExecutorService executorService;//线程池
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();//等待执行队列
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();//正在执行队列(异步)
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();//正在执行队列(同步)
//创建线程池
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;
}
***省略代码
//入队
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
}
promoteAndExecute();
}
//取消所有请求
public synchronized void cancelAll() {
for (AsyncCall call : readyAsyncCalls) {
call.get().cancel();
}
for (AsyncCall call : runningAsyncCalls) {
call.get().cancel();
}
for (RealCall call : runningSyncCalls) {
call.cancel();
}
}
//启动并执行
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
List<AsyncCall> executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
//遍历异步队列
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
//判断是否超过最大值
if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
if (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
executableCalls.add(asyncCall);
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
//遍历可执行队列,并执行
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
asyncCall.executeOn(executorService());
}
return isRunning;
}
//加入同步队列
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
//当前线程结束时,执行空闲回调
private <T> void finished(Deque<T> calls, T call) {
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
idleCallback = this.idleCallback;
}
boolean isRunning = promoteAndExecute();
if (!isRunning && idleCallback != null) {
idleCallback.run();
}
}
***省略代码
}
代码中可以看出,Dispatcher利用三个队列来维持线程池的调度