1.2 Call对象
了解源码或使用过okhttp
的都知道。 okttp
的操作元是Call对象。异步的实现是RealCall.AsyncCall
。而 AsyncCall
是实现的一个Runnable
接口。
- final class AsyncCall extends NamedRunnable {}
所以Call本质就是一个Runable
线程操作元肯定是放进excutorService中直接启动的。
2 线程池的复用和管理
2.1 图解
为了完成调度和复用,定义了两个队列分别用作等待队列和执行任务的队列。这两个队列都是Dispatcher
成员变量。Dispatcher是一个控制执行,控制所有Call的分发和任务的调度、通信、清理等操作。这里只介绍异步调度任务。
-
/** Ready async calls in the order they’ll be run. */
-
private final Deque readyAsyncCalls = new ArrayDeque<>();
-
/** Running asynchronous calls. Includes canceled calls that haven’t finished yet. */
-
private final Deque runningAsyncCalls = new ArrayDeque<>();
在《okhttp连接池复用机制》文章中我们在缓存Connection连接的时候也是使用的Deque双端队列。这里同样的方式,可以方便在队列头添加元素,移除尾部的元素。
2.2 过程分析
Call
代用equeue
方法的时候
-
synchronized void enqueue(AsyncCall call) {
-
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
-
runningAsyncCalls.add(call);
-
executorService().execute(call);
-
} else {
-
readyAsyncCalls.add(call);
-
}
-
}
方法中满足执行队列里面不足最大线程数maxRequests
并且Call对应的host数目不超过maxRequestsPerHost
的时候直接把call对象直接推入到执行队列里,并启动线程任务(Call
本质是一个Runnable
)。否则,当前线程数过多,就把他推入到等待队列中。Call
执行完肯定需要在runningAsyncCalls
队列中移除这个线程。那么readyAsyncCalls
队列中的线程在什么时候才会被执行呢。
追溯下AsyncCall
线程的执行方法
-
@Override
-
protected void execute() {
-
boolean signalledCallback = false;
-
try {
-
Response response = getResponseWithInterceptorChain(forWebSocket);
-
if (canceled) {
-
signalledCallback = true;
-
responseCallback.onFailure(RealCall.this, new IOException(“Canceled”));
-
} else {
-
signalledCallback = true;
-
responseCallback.onResponse(RealCall.this, response);
-
}
-
} catch (IOException e) {
-
if (signalledCallback) {
-
// Do not signal the callback twice!
-
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
-
} else {
-
responseCallback.onFailure(RealCall.this, e);
-
}
-
} finally {
-
client.dispatcher().finished(this);
-
}
-
}
-
}
这里做了核心request的动作,并把失败和回复数据的结果通过responseCallback
回调到Dispatcher。执行操作完毕了之后不管有无异常都会进入到dispactcher
的finished
方法。
-
private void finished(Deque 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();
-
runningCallsCount = runningCallsCount();
-
idleCallback = this.idleCallback;
-
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。
因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-XaPVKB1x-1712529518548)]