プライオリティ順に要素を取得できるQueue
PriorityBlockingQueueなるものを知ったので、使い方を確認するためにサンプルプログラムを書いてみました。
通常のQueueは、先に入った要素から先に取得できる、いわゆるFIFO(First In First Out)になっています。
PriorityBlockingQueueも基本はFIFOですが、プライオリティがより高く設定されているものは、先に取り出すことができるようになっています。
以下がサンプルプログラムです。
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueSample {
public static void main(String[] args) {
PriorityBlockingQueue<Entry> queue = new PriorityBlockingQueue<>();
queue.add(new Entry("one", 2));
queue.add(new Entry("two", 1));
queue.add(new Entry("three", 3));
queue.add(new Entry("four", 5));
queue.add(new Entry("five", 4));
while (queue.size() > 0) {
System.out.println(queue.poll().getValue());
}
}
}
public class Entry implements Comparable<Entry> {
String value;
int priority;
public Entry(String value, int priority) {
this.value = value;
this.priority = priority;
}
String getValue() {
return value;
}
int getPriority() {
return priority;
}
@Override
public int compareTo(Entry other) {
return Integer.compare(this.priority, other.getPriority());
}
}
このプログラムの実行結果は、以下のようになります。
two
one
three
five
four
通常のQueueであればFIFOなので、"one, two, three, four, five"の順に要素を取得できるはずですが、プライオリティを設定してるため、順序が異なっています。
EntryクラスはQueueに入れる用に定義したクラスです。ポイントとしては、Comparableインターフェースを実装し、compareTo関数をオーバーロードすることです。
PriorityBlockingQueue内では、格納されているインスタンスのcompareToメソッドを呼んで、プライオリティの判定を行っています。
今回の例ではpriorityフィールドの値のみを使っていますが、compareToメソッドを書き直せば、priorityが同値ならvalueの値もプライオリティ判定に加える、といったことも可能です。
ジョブの管理をQueueで行っていて、ジョブにプライリティをもたせたいと言った場合に、使えそうなクラスですね。