这个类没有继承任何类或借口,所以他不是一个Queue。
这个类主要维护了几个队列,将request加紧队列然后开启线程处理队列中的request
private final Map<String, Queue<Request>> mWaitingRequests =
new HashMap<String, Queue<Request>>();
这个mWaitingRequests
用于延缓相同的请求进入mCacheQueue
队列中,如果没有mWaitingRequests
,所用的相同请求都会进入mCacheQueue
队列中,假设有n个相同请求都在队列中那么当第一个请求被放到mNetworkQueue
中还没返回请求结果的时候其他所有的都会因为缓存不命中被放到网络请求队列中,结果就是执行了n-1个重复的网络请求。而有了mWaitingRequests
在add(Request request)
函数中判断mWaitingRequests.containsKey(cacheKey)
如果队列中已经有这个key
了那么说明1。第一个加入队列中的request还没有完成网络请求将返回的data
写入cache
因为如果完成了则会调用finish(Request request)
函数,finish(Request request)
中
if (waitingRequests != null) {
if (VolleyLog.DEBUG) {
VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.",
waitingRequests.size(), cacheKey);
}
// Process all queued up requests. They won't be considered as in flight, but
// that's not a problem as the cache has been primed by 'request'.
mCacheQueue.addAll(waitingRequests);
}
这也是为什么加入mWaitingRequests
队列的时候要第一次加入的时候写一个null进队列的原因,这样取出来的时候就可以直接这样mCacheQueue.addAll(waitingRequests)
;
if (mWaitingRequests.containsKey(cacheKey)) {
// There is already a request in flight. Queue up.
Queue<Request> stagedRequests = mWaitingRequests.get(cacheKey);
//LinkedList继承了Dequeue这个借口这是一个双端队列,而Dequeue继承了Queue
if (stagedRequests == null) {
stagedRequests = new LinkedList<Request>();
}
stagedRequests.add(request);
mWaitingRequests.put(cacheKey, stagedRequests);
if (VolleyLog.DEBUG) {
VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);
}
} else {
// Insert 'null' queue for this cacheKey, indicating there is now a request in
// flight.
mWaitingRequests.put(cacheKey, null);
mCacheQueue.add(request);
}
2。或者是第一个request
在cache
队列中,此时其实可以直接将request
加入到cache
队列中的。但为了防止出现前面的那种情况就不做多余的判断直接加入到wait
队列中。性能不会有太大影响。
private final Set<Request> mCurrentRequests = new HashSet<Request>();
这个队列是所有加入到RequestQueue中的request,用于执行
public void cancelAll(RequestFilter filter) {
synchronized (mCurrentRequests) {
for (Request<?> request : mCurrentRequests) {
if (filter.apply(request)) {
request.cancel();
}
}
}
}
将所有的request停掉,为什么不分别停network cache 和wait队列中的request,好像同步也没有问题啊,也不会有多大的性能损失,难道是考虑从network中取出来的request却还没有执行网络请求的request停掉network队列中的元素会漏掉这一个?
PriorityQueue是用heap(堆)实现的优先队列,不允许null值,没有实现同步线程不安全。
PriorityBlockingQueue不是 PriorityQueue的子类但实现和PriorityQueue的功能,并且线程安全,在队列为空的时候将线程block。
private final PriorityBlockingQueue<Request> mCacheQueue =
new PriorityBlockingQueue<Request>();
/** The queue of requests that are actually going out to the network. */
private final PriorityBlockingQueue<Request> mNetworkQueue =
new PriorityBlockingQueue<Request>();
这两个队列分别是准备到cache中和networ中的request默认开启了1个线程处理cache,4个线程处理networ,这是生产者消费者模式啊。