网络请求一般都是交给线程池进行一些耗时的处理。
看一下okhttp异步请求的代码:
使用内部dispatcher对象来执行请求,dispatcher就是调度器,获得调度器之后会调用enqueue这个方法,内部传入了AsyncCall这个对象,而AsyncCall这个对象就是一个Runnable,而在AsyncCall方法当中可以使用okhttp拦截器链传入request最终返回给response。
看一下enqueue这个方法:
就是说当我们满足以上这个条件的时候就会通过线程池executorService执行我们请求的操作。
看一下内部线程池是怎样初始化的:
这个线程池是配置在dispatcher这个类当中的。这个线程池的创建是ThreadPoolExecutor这个对象。
第一个参数0代表核心线程数量,就是保持在线程池当中的线程数量,尽管这些线程可能空闲,但是这个线程数量就是我们关心的。为0就代表线程空闲之后不会被保留,就是说等待一段时间后就会停止。
第二个参数是int整数的最大值,他表示的是线程池中可以容纳的最大线程数量。
第三个keepAliveTime,当我们的线程池中线程数量大于核心线程数量时,空闲线程需要等待60秒的时间才会被终止。如果线程空闲之后,只能存活60秒,如果收到20个并发请求,线程池会创建20个线程,当完成之后会自动关闭20个线程直到60秒,这就是造成阻塞的一个原因。
第四个是一个创建好的等待线程的队列,也是个同步队列。它里面每一个插入操作必须等待另一个线程移除之后才能操作,这个队列当中其实是没有任何一个元素的,可以把它理解为容量为0的一个队列,甚至可以不把他理解为队列,因为他存储的就是Runnable对象,就是说只有一个移除了另外一个才能插入。这种场景适合生产者和消费者场景,就是说可以用最快的方式从生产者转移给消费者,这种场景对于那些高频的网络请求非常适合。
最后一个参数就是线程工厂,直接回创建一个守护线程用来处理dispatcher类。