okhttpのスレッド管理の考え方について
4171 ワード
最近Androidリクエストネットワークがヒットしていますが、公式に採用されているhttpリクエストライブラリはokhttpです.このライブラリの最適化がよく、効率が高いので、スレッドの管理を知りたいので、ソースコードを見てみました.
「スレッドのタスクが完了すると、runningAsyncCallsからこのリクエストが削除され、readyAsyncCallsで実行されていないタスクが実行されることがわかります.
このようなプロセス制御により、スレッドプールのサイズを64スレッド以内に制御し、同じホストのリクエストのスレッドを5つに制御することができ、同じプロジェクトでログと業務リクエストが同時に発生した場合、appの使用に影響を与えず、同時にサブスレッドの数を制御し、appの性能を保証することができる.
総じて,3つの集合を自分で維持することでスレッドプールのサイズを制御し,性能を最適化する.
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
khttp , , Integer.MAX_VALUE, ?
private int maxRequests = 64;//
private int maxRequestsPerHost = 5;//
private final Deque readyAsyncCalls = new ArrayDeque<>();// ,
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
runningAsyncCalls, , 。runningCallsForHost, 。 , maxRequests , maxRequestsPerHost , 。 maxRequests , maxRequestsPerHost , readyAsyncCalls , 。 ?
/** Used by {@code AsyncCall#run} to signal completion. */
synchronized void finished(AsyncCall call) {
if (!runningAsyncCalls.remove(call)) throw new AssertionError("AsyncCall wasn't running!");
promoteCalls();
}
, , , promoteCalls();
private void promoteCalls() {
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
「スレッドのタスクが完了すると、runningAsyncCallsからこのリクエストが削除され、readyAsyncCallsで実行されていないタスクが実行されることがわかります.
このようなプロセス制御により、スレッドプールのサイズを64スレッド以内に制御し、同じホストのリクエストのスレッドを5つに制御することができ、同じプロジェクトでログと業務リクエストが同時に発生した場合、appの使用に影響を与えず、同時にサブスレッドの数を制御し、appの性能を保証することができる.
総じて,3つの集合を自分で維持することでスレッドプールのサイズを制御し,性能を最適化する.