多线程中优先队列的使用示例

使用场景

我们知道队列是遵循先进先出(First-In-First-Out)模式的,但有些时候需要在队列中基于优先级处理对象。

自己在处理爬数据时,代理ip的质量不一,在多线程抓数据时,利用优先队列,优先使用质量好的代理ip。

介绍

优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用Java Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。

优先队列的头是基于自然排序或者Comparator排序的最小元素。如果有多个对象拥有同样的排序,那么就可能随机地取其中任意一个。当我们获取队列时,返回队列的头对象。

优先队列的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Main {
public static void main(String[] args) {
Queue<Integer> queue1 = new PriorityQueue<Integer>();
queue1.add(8);
queue1.add(3);
queue1.add(2);
queue1.add(10);
queue1.add(1);

while (!queue1.isEmpty()) {
System.out.print(queue1.poll() + ",");
}
System.out.println();

Comparator<Integer> cmp;
cmp = new Comparator<Integer>() {
public int compare(Integer e1, Integer e2) {
return e2 - e1;
}
};
Queue<Integer> queue2 = new PriorityQueue<Integer>(5, cmp);
queue2.add(2);
queue2.add(5);
queue2.add(6);
queue2.add(1);
while (!queue2.isEmpty()) {
System.out.print(queue2.poll() + ",");
}
}
}

输出结果为:

1
2
1,2,3,8,10,
6,5,2,1,

第一次按从大到小的方式进行输出。
第二次按从小到大的方式进行输出,传入一个比较对象。

优先队列在代理ip池的方面的应用。

比如某ip,在某次访问超时后,就降低权重。某次访问正常,则增加权重。
按优先队列中按权重来定优先级,这样优先使用总是比较良好的ip。

也可以按ip中的响应时间的平均值来做为优先级。

参考

Java优先队列(PriorityQueue)示例