Okhttp——队列和线程池

版权声明:有些文章写的很随意,那是仅作为个人记录的文章,建议直接关掉,多看一秒亏一秒 https://blog.csdn.net/qq_36523667/article/details/82971821

这是很简单的,但是假如面试官问你,你知道咋回答不?

对于同步:

开始的时候放到同步队列,结束的时候从同步队列中取出;

对于异步:

开始的时候判断异步队列元素数是否大于64?再遍历一遍,看看和这个AsyncCall相同的host有没有超过5个?

如果没有,扔进异步队列;否则,扔进等待队列。

在任务执行完毕后,会把等待队列的任务取出来,重复上述判断。

线程池就不用说了,同步是不用线程池的,后者用全部是非核心的线程池,因为IO、网络操作发起后就等待了,然后这段时间片为了充分利用只好开启新的线程。

有个注意点还是挺有意思的

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();
  }
}

这里有一个idleCallback,这个东西用来通知:所有的请求都已经完成啦。其实也就是运行队列为0的时候会通知下。

看到这里我还有一个疑惑,就是if里的内容放到sync内和sync外有什么区别?

这很简单。如果放到sync内,可以确保运行队列为0的时候,回调触发,这没问题;

如果放到sync外,可能同时有多个线程走到if,假如A线程先到,B线程后到,A线程走到if的时候count=0,然后B走到if的时候count假如等于1,这个时候A的数据就脏了,但是还是会触发回调。看起来是错了,不过这是一个无关紧要的方法,所以不做并发也可以。

猜你喜欢

转载自blog.csdn.net/qq_36523667/article/details/82971821