美文网首页
OKHttp学习笔记(一)

OKHttp学习笔记(一)

作者: _Once1 | 来源:发表于2018-05-20 20:41 被阅读0次

    第一次写博客,说是博客,其实就是自己的学习笔记,希望能坚持下去!


    OKHttp的简单请求示例:

    
    OkHttpClient.Builder builder =new OkHttpClient.Builder();
    
    OkHttpClient client = builder.build();
    
    Request request =new Request.Builder()
    
      .url("")
    
      .build();
    
    try {
    
        // 同步请求
    
        client.newCall(request).execute();
    
        // 异步请求
    
        client.newCall(request).enqueue(new Callback() {
    
            @Override
    
            public void onFailure(Call call, IOException e) {
    
    }
    
            @Override
    
            public void onResponse(Call call, Response response)throws IOException {
    
    }
    
    });
    
    } catch (IOException e) {
    
      e.printStackTrace();
    
    }
    
    

    以下是自己做的请求顺序导图:

    请求顺序

    结合图总结一下异步请求过程

    • 如果满足异步执行条件,则入队并立即执行,否则,加入ready队列,等待合适的条件去将其取出;当一个请求执行结束,会调用Dispatcher的promoteCalls方法,会将ready队列中的AsyncCall取出,入队并开始执行,然后在线程池中调用所执行的Call的getResponseWithInterceptorChain(),获取到请求结果,并回调出去。
    • 同步异步的执行区别:都是调用的getResponseWithInterceptorChain()方法,异步线程是通过线程池来执行的,而同步则是直接执行

    Dispatcher类

    1. 线程池
    该类中,获取线程池的方法为executorService(),该方法内部实现的是懒加载的无边界限制的线程池。

    if (executorService == null) {
          executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
              new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    

    可见,OKHttp中使用的线程池是ThreadPoolExecutor
    参数说明:

    • 0:核心线程数量,0表示后台线程空闲后不会保留,经过一段时间后停止
    • Integer.MAX_VALUE:线程池可容纳的最大线程数量
    • TimeUnit.SECOND:线程池中的线程数量大于核心线程数量时,空闲线程等待60s即被终止,若小于,则立即终止
    • new SynchronousQueue<Runnable>():线程等待队列
    • 最后一个参数:线程工厂
      这里,需要对SynchronousQueue进行说明:
      该队列的特点是:每插入一个元素必须等待另一个元素的移除,每移除一个元素都会等待另一个元素的插入,也就是说,该队列内部其实没有元素,容量为0;这样设计的意义就是可以快速的传递元素,很适合高频率的请求处理。

    2. 结束请求finished方法

    • 先移除该call对象
    • 根据传入的promoteCalls参数,确定是否调用promoteCalls()方法;若为同步请求,则该参数为false,若为异步请求,则参数为true,需要执行下一步的入队操作

    3. promoteCalls()方法
    该方法是操作队列,控制请求执行的关键,负责将ready队列的call转化为running状态

    • 首先,它会判断当前执行的request是否大于64
    • 若小于,则遍历ready队列,取出call并将其添加进running队列,调用线程池的execute(call)方法
    • 遍历的终止条件:ready队列为空,或者running满足最大数量限制
      回调该方法有三个时机:
    • 一个请求执行结束,finished方法中
    • Dispatcher的setMaxRequestsPerHost()被调用
    • Dispatcher的setMaxRequests()被调用

    总结
    该类控制着异步请求时的任务调度和线程池,并未直接负责请求的执行,配合线程池,实现了高并发,低阻塞的运行。


    参考:这位大佬的博客

    相关文章

      网友评论

          本文标题:OKHttp学习笔记(一)

          本文链接:https://www.haomeiwen.com/subject/hlatjftx.html