Java PriorityQueue和PriorityBlockingQueue
在这些计划中,我应该选择哪一个?为什么?一般来说,问题是为什么我应该选择使用PriorityBlockingQueue而不是PriorityQueue 优先阻塞队列Java PriorityQueue和PriorityBlockingQueue,java,java.util.concurrent,Java,Java.util.concurrent,在这些计划中,我应该选择哪一个?为什么?一般来说,问题是为什么我应该选择使用PriorityBlockingQueue而不是PriorityQueue 优先阻塞队列 import java.util.concurrent.PriorityBlockingQueue; public class PriorityBlockingQueueExample { static PriorityBlockingQueue<String> priorityQueue = new Pri
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
static PriorityBlockingQueue<String> priorityQueue = new PriorityBlockingQueue<String>();
public static void main(String[] args) {
new Thread(){
public void run(){
try {
System.out.println(priorityQueue.take() +" is removed from priorityQueue object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
new Thread(){
public void run(){
priorityQueue.add("string variable");
System.out.println("Added an element to the queue");
}
}.start();
}
}
import java.util.concurrent.PriorityBlockingQueue;
公共类优先级BlockingQueueExample{
静态PriorityBlockingQueue priorityQueue=新建PriorityBlockingQueue();
公共静态void main(字符串[]args){
新线程(){
公开募捐{
试一试{
System.out.println(priorityQueue.take()+“已从priorityQueue对象中删除”);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}.start();
新线程(){
公开募捐{
添加(“字符串变量”);
System.out.println(“向队列添加了一个元素”);
}
}.start();
}
}
在这些计划中,我应该选择哪一个?为什么?一般来说,问题是为什么我应该选择使用PriorityBlockingQueue而不是PriorityQueue。
优先队列
import java.util.PriorityQueue;
public class PriorityQueueTest {
static PriorityQueue<String> priorityQueue = new PriorityQueue<String>();
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(){
public void run(){
synchronized(lock){
try {
while(priorityQueue.isEmpty()){lock.wait();}
System.out.println(priorityQueue.remove() +" is removed from priorityQueue object");
lock.notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread(){
public void run(){
synchronized(lock){
priorityQueue.add("string variable");
System.out.println("Added an element to the queue");
lock.notify();
}
}
}.start();
}
}
import java.util.PriorityQueue;
公共类优先级队列测试{
静态优先级队列优先级队列=新建优先级队列();
私有静态对象锁=新对象();
公共静态void main(字符串[]args){
新线程(){
公开募捐{
已同步(锁定){
试一试{
while(priorityQueue.isEmpty()){lock.wait();}
System.out.println(priorityQueue.remove()+“从priorityQueue对象中删除”);
lock.notify();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}.start();
新线程(){
公开募捐{
已同步(锁定){
添加(“字符串变量”);
System.out.println(“向队列添加了一个元素”);
lock.notify();
}
}
}.start();
}
}
正常的队列
如果是空的,当被访问时将返回null
,而阻塞队列
如果队列是空的,则阻塞,直到有值可用为止
您正在使用的队列中的优先级部分仅意味着按照特定顺序从队列中读取项目(如果它们实现了可比
,则是自然的,或者根据比较器
)
通常,您可以依赖于抽象类型,PriorityQueue
或BlockingQueue
。如果您的代码需要了解这两个概念,则可能需要重新思考
您可能需要一个可归结为消息排序的PriorityQueue
,原因有很多。例如,在作业队列中,您可能希望能够为这些作业赋予优先级。也就是说,处理作业的代码通常应该与订单无关
使用
BlockingQueue
时,您通常处于工作线程接收排队工作的领域,当没有工作要做时,这些线程可以被阻止,直到工作可用为止。与PriorityQueue
的示例类似,调用代码可能与此无关,尽管您可能希望使用某种并非总是如此的等待超时。PriorityBlockingQueue是与JDK 5中的并发包一起添加的,请参阅:
它基本上是在幕后完成您为PriorityQueue编写的额外代码,即在队列周围添加通常需要的synchronize/wait/notify。因此,名称的“阻塞”部分被添加,这意味着线程将阻塞等待,直到队列中有可用的项
如果你的应用程序可以在JDK 5或更新版上运行,我会使用PrimyIsBuffjQue}。< /P> < P>我知道这是一个老话题,但是我看到你没有考虑同时实现一个优先级队列。 尽管java的collections框架没有,但它有足够的构建块来创建一个:
public class ConcurrentSkipListPriorityQueue<T> implements Queue<T> {
private ConcurrentSkipListMap<T, Boolean> values;
public ConcurrentSkipListPriorityQueue(Comparator<? super T> comparator) {
values = new ConcurrentSkipListMap<>(comparator);
}
public ConcurrentSkipListPriorityQueue() {
values = new ConcurrentSkipListMap<>();
}
@Override
public boolean add(T e) {
values.put(e, Boolean.TRUE);
return true;
}
@Override
public boolean offer(T e) {
return add(e);
}
@Override
public T remove() {
while (true) {
final T v = values.firstKey();
if (values.remove(v)) {
return v;
}
}
}
@Override
public T poll() {
try {
while (true) {
if (values.isEmpty()) {
return null;
}
final T v = values.firstKey();
if (values.remove(v)) {
return v;
}
}
} catch (NoSuchElementException ex) {
return null; // poll should not throw an exception..
}
}
@Override
public T element() {
return values.firstKey();
}
@Override
public T peek() {
if (values.isEmpty()) {
return null;
}
try {
return element();
} catch (NoSuchElementException ex) {
return null;
}
}
@Override
public int size() {
return values.size();
}
@Override
public boolean isEmpty() {
return values.isEmpty();
}
@Override
public boolean contains(Object o) {
return values.containsKey(o);
}
@Override
public Iterator<T> iterator() {
return values.keySet().iterator();
}
@Override
public Object[] toArray() {
return values.keySet().toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return values.keySet().toArray(a);
}
@Override
public boolean remove(Object o) {
return values.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return values.keySet().containsAll(c);
}
@Override
public boolean addAll(Collection<? extends T> c) {
boolean changed = false;
for (T i : c) {
changed |= add(i);
}
return changed;
}
@Override
public boolean removeAll(Collection<?> c) {
return values.keySet().removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return values.keySet().retainAll(c);
}
@Override
public void clear() {
values.clear();
}
}
公共类ConcurrentSkipListPriorityQueue实现队列{
私有ConcurrentSkipListMap值;
公共ConcurrentSkipListPriorityQueue(比较器c){
返回值.keySet().containsAll(c);
}
@凌驾
公共布尔addAll(集合c){
返回值.keySet().removeAll(c);
}
@凌驾
公共布尔保留(集合c){
返回值.keySet().retainal(c);
}
@凌驾
公共空间清除(){
value.clear();
}
}
此队列基于跳过列表,将其所有操作委托给ConcurrentSkipListMap类。它允许来自多个线程的非阻塞并发访问。这是什么时候的优先级队列?就目前的情况而言,它是无用的。