1.正在执行的任务数量最大值是64
异步请求放入readyAsyncCalls后,遍历readyAsyncCalls取出任务去执行的时候,如果发现runningAsyncCalls的数量大于等于64,就不从readyAsyncCalls取出任务执行。
java
public final class Dispatcher {
private int maxRequests = 64;
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
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 (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
//从readyAsyncCalls remove
i.remove();
//callsPerHost+1
asyncCall.callsPerHost().incrementAndGet();
//添加到executableCalls
executableCalls.add(asyncCall);
//添加到runningAsyncCalls
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;
}
}
2.同一个主机的最大连接数为5
异步请求放入readyAsyncCalls后,遍历readyAsyncCalls取出任务去执行的时候,如果发现asyncCall的callsPerHost大于等于5,就不从readyAsyncCalls取出任务执行;否则callsPerHost加1。
java
public final class Dispatcher {
private int maxRequestsPerHost = 5; //默认5。这是okhttp对同一主机允许的最大请求数量。
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
//Mutate the AsyncCall so that it shares the AtomicInteger
//of an existing running call to the same host.
if (!call.get().forWebSocket) {
//从已经存在的任务里面找同一个主机的任务
AsyncCall existingCall = findExistingCallWithHost(call.host());
if (existingCall != null) {
//call的将callsPerHost赋值为existingCall的callsPerHost
call.reuseCallsPerHostFrom(existingCall);
}
}
}
promoteAndExecute();
}
//有个疑问,这里是不是要从ArrayDeque尾向前获取,才能获取到最新的AsyncCall,这样获取到的
//callsPerHost才会是最大的?
//目前从头开始获取,是不是有问题?
//先从runningAsyncCalls找,再从readyAsyncCalls找
@Nullable
private AsyncCall findExistingCallWithHost(String host) {
for (AsyncCall existingCall : runningAsyncCalls) {
if (existingCall.host().equals(host)) {
return existingCall;
}
}
for (AsyncCall existingCall : readyAsyncCalls) {
if (existingCall.host().equals(host)) {
return existingCall;
}
}
return null;
}
}