java PriorityBlockingQueue——按优先级排序的阻塞式线程安全列表
数据结构应用中的一个经典需求是实现一个有序列表,java引入了priorityBlockingQueue类来满足这类需求。
所有添加进PriorityBlockingQueue的元素必须实现Comparable接口,这个借口提供了CompareTo()方法,他的传入参数是一个同类型的对象。这样就有了两个同类型的对象并且相互比较:其中一个是执行这个方法的对象,另一个是参数传入的对象。这个方法必须返回一个数字值,如果当前对象小于参数传入的对象,那么返回一个小于0的值,如果当前对象大于参数传入的对象,那么返回一个大于0的值;如果两个对象相等就返回0。
当插入元素时,PriorityBlockingQueue使用compareTo()方法来决定插入元素的位置。元素越大越靠后。
PriortyBlockingQueue的另一个重要的特性是,它是阻塞式数据结构(BlockingDataStructure)。当它的方法被调用并且不能立即执行时,调用这个方法的线程将被阻塞直到方法执行成功。
下面这个小例子主要是介绍这个队列的使用和检查队列是否按预期排序,以及在多线程中是怎么使用的。
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueDemo {
public static void main(String[] args) {
PriorityBlockingQueue<Event> queue = new PriorityBlockingQueue<Event>();
Thread[] taskThreads = new Thread[5];
for (int i = 0; i < taskThreads.length; i++) {
Task task = new Task(i,queue);
taskThreads[i] = new Thread(task);
}
for (int i = 0; i < taskThreads.length; i++) {
taskThreads[i].start();
}
for(int i = 0; i < taskThreads.length; i++) {
try {
taskThreads[i].join();//等待五个线程执行结束
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("Main Queue Size: %d\n", queue.size());
for(int i = 0; i < taskThreads.length*200; i++) {
Event event = queue.poll();
System.out.printf("Thread %s: Priority %d\n",event.getThread(),event.getPriority());
}
System.out.printf("Main Queue Size: %d\n",queue.size());
System.out.printf("Main: End of the program\n");
}
}
class Event implements Comparable<Event> {
private int thread;
private int priority;
public Event(int thread, int priority) {
this.thread = thread;
this.priority = priority;
}
public int getThread () {
return thread;
}
public int getPriority() {
return priority;
}
@Override
public int compareTo (Event e) {
if (this.priority < e.getPriority()) {
return -1;
} else if (this.priority > e.getPriority()) {
return 1;
} else {
return 0;
}
}
}
class Task implements Runnable {
private int id;
private PriorityBlockingQueue<Event> queue;
public Task(int id,PriorityBlockingQueue<Event> queue) {
this.id = id;
this.queue = queue;
}
@Override
public void run() {
for (int i = 0; i < 200; i++) {
Event event = new Event(id,i);
queue.offer(event);
}
}
}