版权声明:有些文章写的很随意,那是仅作为个人记录的文章,建议直接关掉,多看一秒亏一秒 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的数据就脏了,但是还是会触发回调。看起来是错了,不过这是一个无关紧要的方法,所以不做并发也可以。