Volley中使用的优先级队列 PriorityQueue

代码示例

摘取自:

http://java-er.com/blog/java-priority-queue/

package com.javaer.examples.datastruct;
 
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
 
import org.apache.poi.ss.formula.functions.Count;
 
public class PriorityQueueExample {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Queue qi = new PriorityQueue();
 
            qi.add(5);
            qi.add(2);
            qi.add(1);
            qi.add(10);
            qi.add(3);
 
            while (!qi.isEmpty()){
              System.out.print(qi.poll() + ",");
            }
            System.out.println();
            System.out.println("-----------------------------");
 
            Comparator cmp;
            cmp = new Comparator() {
              public int compare(Integer e1, Integer e2) {
                return e2 - e1;
              }
            };
            Queue q2 = new PriorityQueue(5,cmp);
            q2.add(2);
            q2.add(8);
            q2.add(9);
            q2.add(1);
            while (!q2.isEmpty()){
                  System.out.print(q2.poll() + ",");
                }
    }
 
}

output:


1,2,3,5,10,
-----------------------------
9,8,2,1,
优先级队列的特点

对它里面的元素,按照设定的规则进行排序. 从队列取数据的时候, 按照排序后的顺序取里面的元素.

PriorityQueue implement Queue

普通队列的特点是, 对取元素的操作进行了限制, 只能从队列头取元素, 不能从任意位置取元素.
而优先级队列对它里面的元素进行了排序, 默认使用元素的自然排序, 当然也可以构造PriorityQueue的时候, 指定一个比较器, 按照比较器的规则对元素进行排序.

这就要求插入到优先级队列中的元素, 都必须是实现了Comparable接口的对象.

PriorityQueue不是线程安全的, 如果有多个线程对同一个优先级队列进行操作, 需要使用PriorityBlockingQueue这个类.

Queue
BlockingQueue
PriorityBlockingQueue
PriorityBlockingQueue的应用场景.

Volley中使用PriorityBlockingQueue存储外界对volley的网络请求.

public class RequestQueue {
    /** The cache triage queue. */
    private final PriorityBlockingQueue> mCacheQueue =
        new PriorityBlockingQueue>();

    /** The queue of requests that are actually going out to the network. */
    private final PriorityBlockingQueue> mNetworkQueue =
        new PriorityBlockingQueue>();

}

在构造的时候, 并没有指定一个比较器, 实际上对元素进行排序时, 实际上是调用每个元素的getPriority()方法, 当priority一致的情况下, 比较的是request的mSequence值.

public abstract class Request implements Comparable> {
    /**
     * Sequence number of this request, used to enforce FIFO ordering.
     */
    private Integer mSequence;

    @Override
    public int compareTo(Request other) {
        Priority left = this.getPriority();
        Priority right = other.getPriority();

        // High-priority requests are "lesser" so they are sorted to the front.
        // Equal priorities are sorted by sequence number to provide FIFO ordering.
        return left == right ?
                this.mSequence - other.mSequence :
                right.ordinal() - left.ordinal();
    }
}

//图片的网络请求类

public class ImageRequest extends Request {
    @Override
    public Priority getPriority() {
        return Priority.LOW;
    }
}

//文本的网络请求类根本就没有override getPriority()方法

public class StringRequest extends Request {

}

volley定义了4个请求优先级, 但实际上所有网络请求类的getPriority()返回的都是Priority.LOW, 并且没有提供设置优先级的API.

public abstract class Request implements Comparable> {
    public enum Priority {
        LOW,
        NORMAL,
        HIGH,
        IMMEDIATE
    }

}
对volley的扩展

要想设置优先级, 可以扩展自己的网络请求类.

public class MyImageRequest extends ImageRequest {
    private Priority mPriority = Priority.LOW;

    @Override
    public Priority getPriority() {
        return mPriority;
    }

//新加个API去设置优先级
    public void setPriority(Priority priority) {
        mPriority = priority;
    }
}

或是使用匿名内部类.

StringRequest request = new StringRequest(Request.Method.GET,"feed URL",volleyListener, volleyErrorListener) {
    @Override
    public Priority getPriority() {
        return Priority.IMMEDIATE;
    }
};
对volley的优化

volley还是不够灵活, 所有的请求都是FIFO ordering先进先出.

有这么一个场景, 在滑动listview的时候, 希望后添加进去的请求先被执行,因为后添加的item肯定是在用户的可见区, volley默认是实现不了的.

可以在初始化

private final PriorityBlockingQueue> mCacheQueue =
        new PriorityBlockingQueue>();

时候, 给PriorityBlockingQueue提供一个自定义的比较器.

    public PriorityBlockingQueue(int initialCapacity,
                                 Comparator comparator)

在比较器中, 实现API

public int compare(T lhs, T rhs);

这样就可以实现PriorityBlockingQueue中所有元素的反向排序, 实现先进后出.

通过设置不同的比较器, 实现优先级队列的正向, 反向排序, 使用的就是设计模式中的策略模式.

----DONE.---------

你可能感兴趣的:(Volley中使用的优先级队列 PriorityQueue)