模板设计模式(三) - OkHttp的 Dispatcher(线程池)

前言

模板设计模式系列文章
模板设计模式(一) - 定义及源码中所用到的模板设计模式
模板设计模式(二) - 线程池工作机制
模板设计模式(三) - OkHttp的 Dispatcher(线程池)

1. 概述


前边两节我们分析了模板设计模式的定义、源码中哪些都用到了模板设计模式、线程池工作机制,那么这节课我们就来看下OkHttp中的 Dispatcher(线程池);

  • 针对于Dispatcher中的 ExecutorService可以参照我之前的文章:
    Android线程管理 - ExecutorService线程池

2. OkHttp中的 Dispatcher(线程池)源码分析


/**
 * Policy on when async requests are executed.
 *
 * 

Each dispatcher uses an {@link ExecutorService} to run calls internally. If you supply your * own executor, it should be able to run {@linkplain #getMaxRequests the configured maximum} number * of calls concurrently. */ public final class Dispatcher { // 最大请求是 64 private int maxRequests = 64; private int maxRequestsPerHost = 5; private @Nullable Runnable idleCallback; // 线程池 private @Nullable ExecutorService executorService; // 准备执行 private final Deque readyAsyncCalls = new ArrayDeque<>(); // 正在执行(同步) private final Deque runningAsyncCalls = new ArrayDeque<>(); // 正在执行(异步) private final Deque runningSyncCalls = new ArrayDeque<>(); public Dispatcher(ExecutorService executorService) { this.executorService = executorService; } public Dispatcher() { } public synchronized ExecutorService executorService() { if (executorService == null) { // executorService如果为null,就创建线程池对象 executorService = new ThreadPoolExecutor( 0, // 核心线程数: 为0 Integer.MAX_VALUE, // 最大线程数: 为最大 60, // 线程存活时间是60秒: 60秒之内如果缓存队列中没有可执行的任务,就会销毁线程 TimeUnit.SECONDS, // 单位:秒 new SynchronousQueue(), // 线程安全的队列,它里边没有固定的缓存(OkHttp所用的) Util.threadFactory("OkHttp Dispatcher", false)); // 创建线程:直接 new Thread() } return executorService; } /** * Set the maximum number of requests to execute concurrently. Above this requests queue in * memory, waiting for the running calls to complete. * *

If more than {@code maxRequests} requests are in flight when this is invoked, those requests * will remain in flight. */ public synchronized void setMaxRequests(int maxRequests) { if (maxRequests < 1) { throw new IllegalArgumentException("max < 1: " + maxRequests); } this.maxRequests = maxRequests; promoteCalls(); } public synchronized int getMaxRequests() { return maxRequests; } /** * Set the maximum number of requests for each host to execute concurrently. This limits requests * by the URL's host name. Note that concurrent requests to a single IP address may still exceed * this limit: multiple hostnames may share an IP address or be routed through the same HTTP * proxy. * *

If more than {@code maxRequestsPerHost} requests are in flight when this is invoked, those * requests will remain in flight. */ public synchronized void setMaxRequestsPerHost(int maxRequestsPerHost) { if (maxRequestsPerHost < 1) { throw new IllegalArgumentException("max < 1: " + maxRequestsPerHost); } this.maxRequestsPerHost = maxRequestsPerHost; promoteCalls(); } public synchronized int getMaxRequestsPerHost() { return maxRequestsPerHost; } /** * Set a callback to be invoked each time the dispatcher becomes idle (when the number of running * calls returns to zero). * *

Note: The time at which a {@linkplain Call call} is considered idle is different depending * on whether it was run {@linkplain Call#enqueue(Callback) asynchronously} or * {@linkplain Call#execute() synchronously}. Asynchronous calls become idle after the * {@link Callback#onResponse onResponse} or {@link Callback#onFailure onFailure} callback has * returned. Synchronous calls become idle once {@link Call#execute() execute()} returns. This * means that if you are doing synchronous calls the network layer will not truly be idle until * every returned {@link Response} has been closed. */ public synchronized void setIdleCallback(@Nullable Runnable idleCallback) { this.idleCallback = idleCallback; } 如果请求数量 < 64,就会加入到runningAsyncCalls(运行时的);否则加入到 readyAsyncCalls 然后每执行完后,都会把 readyAsyncCalls 中移入到 runningAsyncCalls中 /** * 如果正在执行的runningAsyncCalls数量 < 64,就会加入到runningAsyncCalls(运行时的); * 否则加入到 readyAsyncCalls */ synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); executorService().execute(call); } else { readyAsyncCalls.add(call); } } /** * Cancel all calls currently enqueued or executing. Includes calls executed both {@linkplain * Call#execute() synchronously} and {@linkplain Call#enqueue asynchronously}. */ public synchronized void cancelAll() { for (AsyncCall call : readyAsyncCalls) { call.get().cancel(); } for (AsyncCall call : runningAsyncCalls) { call.get().cancel(); } for (RealCall call : runningSyncCalls) { call.cancel(); } } /* * 在这里会做一些移动操作: * 如果 正在执行的 runningAsyncCalls.size() 数量 > 64,就不要再做了; */ 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. } } /** Returns the number of running calls that share a host with {@code call}. */ private int runningCallsForHost(AsyncCall call) { int result = 0; for (AsyncCall c : runningAsyncCalls) { if (c.host().equals(call.host())) result++; } return result; } /** Used by {@code Call#execute} to signal it is in-flight. */ synchronized void executed(RealCall call) { runningSyncCalls.add(call); } /** Used by {@code AsyncCall#run} to signal completion. */ void finished(AsyncCall call) { finished(runningAsyncCalls, call, true); } /** Used by {@code Call#execute} to signal completion. */ void finished(RealCall call) { finished(runningSyncCalls, call, false); } 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; } if (runningCallsCount == 0 && idleCallback != null) { idleCallback.run(); } } /** Returns a snapshot of the calls currently awaiting execution. */ public synchronized List queuedCalls() { List result = new ArrayList<>(); for (AsyncCall asyncCall : readyAsyncCalls) { result.add(asyncCall.get()); } return Collections.unmodifiableList(result); } /** Returns a snapshot of the calls currently being executed. */ public synchronized List runningCalls() { List result = new ArrayList<>(); result.addAll(runningSyncCalls); for (AsyncCall asyncCall : runningAsyncCalls) { result.add(asyncCall.get()); } return Collections.unmodifiableList(result); } public synchronized int queuedCallsCount() { return readyAsyncCalls.size(); } public synchronized int runningCallsCount() { return runningAsyncCalls.size() + runningSyncCalls.size(); } }

OkHttp就是用 executorService 执行请求的,RxJava也是用线程池执行请求的

你可能感兴趣的:(模板设计模式(三) - OkHttp的 Dispatcher(线程池))