OkHttp 原理解析 - 线程调度
1 | // 基本使用 |
线程调度
newCall 返回 RealCall 对象
调用 RealCall 对象的 enqueue 方法:
1
2
3
4
5
6
7
8
9
10// RealCall.class
override fun enqueue(responseCallback: Callback) {
synchronized(this) {
check(!executed) { "Already Executed" }
executed = true
}
callStart() // 调用前期准备,如添加监听
3. 使用调度器将 call 加入队列,AsyncCall 是 RealCall 内部类,持有 RealCall 对象
client.dispatcher.enqueue(AsyncCall(responseCallback))
}使用调度器将 call 加入队列
1
2
3
4
5
6
7
8
9
10
11// Dispatcher.class
internal fun enqueue(call: AsyncCall) {
synchronized(this) {
readyAsyncCalls.add(call)
if (!call.call.forWebSocket) {
val existingCall = findExistingCallWithHost(call.host)
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)
}
}
promoteAndExecute() // 4. 从 readyAsyncCalls 中拿出 call 并放入 runningAsyncCalls,执行任务
}promoteAndExecute()
每当 maxRequests/maxRequestsPerHost/call 调用 enqueue/call finish,都会执行promoteAndExecute()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26private fun promoteAndExecute(): Boolean {
this.assertThreadDoesntHoldLock()
val executableCalls = mutableListOf<AsyncCall>()
val isRunning: Boolean
synchronized(this) {
val i = readyAsyncCalls.iterator()
while (i.hasNext()) {
val asyncCall = i.next()
if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.
if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity.
i.remove()
asyncCall.callsPerHost.incrementAndGet()
// 将 call 加入可执行列表
executableCalls.add(asyncCall)
// 将 call 加入运行中列表
runningAsyncCalls.add(asyncCall)
}
isRunning = runningCallsCount() > 0
}
for (i in 0 until executableCalls.size) {
// 遍历可执行列表中的任务并放入线程池 executorService 中执行
val asyncCall = executableCalls[i]
asyncCall.executeOn(executorService)
}
return isRunning
}
实用工具
- 更新token
1 | [OkHttpClient].authenticator(object : Authenticator { |