美文网首页Android技术知识
OkHttp3源码学习之Dispatcher

OkHttp3源码学习之Dispatcher

作者: 辰静暮夕 | 来源:发表于2017-05-30 20:30 被阅读0次

    介绍

    Dispatcher对应于应用层,通过Dispatcher实现线程的复用

    源码分析

    Dispatcher源码架构

    重点分析executorService()finishedpromoteCalls()

    executorService()

    //executorService是否为空,可以自定义线程池 
    if (executorService == null) {
        //构建一个最少为0,最多无限制,空闲存活时间为60秒,
        executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
        //无缓冲队列,线程工厂名为OkHttp Dispatcher
        new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
    

    内置的executorService是一个无缓冲,先进先出的线程池,可以适应于一般的网络请求,如果是其他有一定要求的请求,比如列表图片加载(有优先级),可能就不太适用了。

    finished

    private <T> void finished(Deque<T> 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();
        }
      }
    

    通过finished方法来主动控制线程的调度。

    promoteCalls

      private void promoteCalls() {
        //线程阻塞
        if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
        if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
        for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
          AsyncCall call = i.next();
          //判断Host相同的Request已满
          if (runningCallsForHost(call) < maxRequestsPerHost) {
            i.remove();
            runningAsyncCalls.add(call);
            executorService().execute(call);
          }
          //可能添加线程到满
          if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
        }
      }
    

    扩展

    Dispatcher向我们展示了怎样创建一个高并发,底阻塞,主动调度的线程池,想要了解更多的线程创建优化,建议阅读《Effectivie Java》并发章节

    相关文章

      网友评论

        本文标题:OkHttp3源码学习之Dispatcher

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