面试

OkHttp底层原理

2021-03-04  本文已影响0人  flynnny

总结自https://www.bilibili.com/video/BV1sT4y1P7mH

现在的HttpURLConnection底层实现也采用的是OkHttp。
HTTP协议是应用层协议,要HTTP通信先要建立TCP连接。使用一个连接池放入所有的tcp连接。不需要每次通信完成三次握手减少了请求延迟。

1.png

分发器Dispatcher,负责请求任务什么时候执行

http请求会经过什么步骤?
1、域名解析DNS--得到IP,
2、根据IP建立TCP连接(经过三次握手)---得到Socket对象。
3、利用Socket输出流写出Http报文。

拦截器就是负责完成上述过程的。+各种优化(连接池)

分发器Dispatcher

*利用OkhttpClient的Builder模式可以构建自己的Dispatcher

从call开始看

2.png 3.png

得到RealCall后 调用同步/异步的执行方法执行
异步请求enqueue(Callback):

4.png

即调用call的异步请求

5.png

回到enqueue(Callback):
先Synchronized(this){...},如果这个call被调用了则抛出异常,所以call只能调用一次。如果想多次调用要clone().

Call clone = call.clone();
clone.enqueue(new Callback(){...});

eventListener 里面可以监听dns解析开始、请求开示等过程

最后一句:

client.dispatcher().enqueue(new AsyncCall(responseCallback));

说明最终会调用到分发器的enqueue方法!传了一个AsyncCall(是一个Runnable)
进入分发器

6.png 7.png

先看异步的,三个问题:
1、call进来是如何判断放入等待队列还是运行队列的?
2、当call进入运行队列,应为是异步的、同时运行多个线程,需要一个线程池(ThreadPool)来管理,ready-》Running条件是什么
3、分发器里的线程池定义、维护

8.png

问题一回答:
正在执行的异步请求个数不大于默认64个
&&同一个域名请求最大数不大于默认5个

问题二回答:
每次执行完一个请求

9.png 10.png

calls.remove(call)方法移除请求完的call
promoteCalls()方法代码如下:

11.png

从ready获取一个方法放到running执行

问题三回答:

12.png

里面是一个SynchoronousQueue<Runnable> queue类型的线程池,这个线程池特点是没有容量。每次来任务时走判断流程都会初始化一个线程,实现高并发无阻塞

13.png 14.png

对同步请求 会加入runningSyncCalls,然后执行,只是一个记录的作用

拦截器

这一行执行拦截器

15.png 16.png

采用责任链设计模式

17.png

U型的、逐个运行完后按顺序返回

18.png

*OKHttp设置缓存后才会开启缓存。

上一篇下一篇

猜你喜欢

热点阅读