OKhttp(原理,同步异步 Dispacther)

172 阅读1分钟

原链接:juejin.cn/post/701551…

  1. 调用流程:至少需要OkHttpClient、Request、Call、Response

    1. 分发器:队列 + 线程池,完成需求调配
    2. 拦截器:五大默认拦截器完成整个请求过程 image.png
  2. Socket复用(TCP三次握手,四次挥手) 2.1 发起http请求时要经历三次握手,四次挥手 image.png 2.2 高并发请求连接情况下或通过客户端多次请求,无限制创建导致性能低下。http有个keepalive connections机制,传输数据后保持连接,再次请求后无需握手 2.3 OkHttp支持5个并发KeepAlive,默认链路5min(保活时间) image.png

  3. ConnectionPool连接池 image.png 3.1 缓存操作:ConnectionPool对Deque操作 3.1.1 put 放入连接 image.png 3.1.2 get 获取连接 image.png 3.1.3 executor.execute(cleanupRunnable) 3.1.3.1 cleanupRunnable image.png 3.1.3.2 cleanup image.png 3.1.3.3 pruneAndGetAllocationCount image.png

3.任务分发:高并发请求队列

image.png

Dispatcher分发器源码解析 image.png

  1. execute 同步 最终走到dispatcher.execute image.png
  2. enqueue 异步 最终走到dispatcher.enqueue image.png call:本质上就是runnable 只需要关注网络请求结束后会调用dispatcher.finished - > promoteCalls

image.png

在等待队列的请求如何迁移到正在执行的队列 image.png

关于OKHttp同步与异步问题

  1. execute同步:OkHttp会立即在当前线程执行HTTP请求,并阻塞该线程,请求完成后会返回Response对象,请求失败会抛出IOException。先判断是否执行过,请求放入同步执行队列,通过getResponseWiteInterceptorChain获取响应结果
  2. enqueue异步:OkHttp发起异步请求,不阻塞当前线程,请求结果通过CallBack通知调用者。通过AsyncCall对象加入到异步准备队列,Dispatcher的promoteAndExecute将异步准备队列中AsyncCall对象取出,加入异步执行队列,通过线程池执行