2012-03-08 1 views
0

У меня есть PriorityBlockingQueue следующим образом:PriorityBlockingQueue не блокирует?

BlockingQueue<Robble> robbleListQueue = new PriorityBlockingQueue<Robble>(); 

Robble реализует Comparable<Robble> и я могу сортировать списки без проблем, так что я знаю, что мои сравнения работы.

У меня также есть следующие Runnable:

private class RobbleGeneratorRunnable implements Runnable { 
    private final BlockingQueue<Robble> robbleQueue; 
    public RobbleGeneratorRunnable(BlockingQueue<ResultList> robbleQueue) { 
     this.robbleQueue = robbleQueue; 
    } 
    @Override 
    public void run() { 
     try { 
      robbleQueue.put(generateRobble()); 
     } catch (InterruptedException e) { 
      // ... 
     } 
    } 

    private Robble generateRobble() { 
     // ... 
    } 
} 

я нажимаю несколько тысяч этих runnables в ExecutorService, а затем shutdown() и awaitTermination().

В соответствии с BlockingQueue JavaDoc, put(...) является блокирующим действием. Однако, когда я повторяю элементы в очереди, они в основном по порядку - есть некоторые, которые не соответствуют порядку, что указывает на то, что очередь не блокируется должным образом. Как я уже говорил, я могу сортировать Robble, просто отлично.

Что может быть причиной того, что robbleQueue.put(generateRobble()) не заблокировать правильно?

ответ

1

Итерация PriorityQueue или PriorityBlockingQueue явно указывается в Javadoc, который нельзя заказывать. Только add(), peek(), poll() и remove() приказаны. Это не имеет никакого отношения к тому, что блокирование происходит правильно.

1

PriorityBlockingQueue неограниченная очереди, и если вы читаете Javadocs для пут() говорится:

вставляет указанный элемент в этой приоритетной очереди. Поскольку очередь не ограничена, этот метод никогда не будет блокироваться.

Почему вы ожидаете, что put() заблокировать?

+0

См. Таблицу на [этой странице] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html). 'put (e)' in в столбце 'Blocks'. Разве это не нарушение в контракте по реализации интерфейса «BlockingQueue»? –

+0

С страницы, которую вы указали: 'БлокировкаQueue может быть ограничена пропускной способностью. В любой момент времени он может иметь оставшуюся емкость, за которой дополнительные элементы не могут быть помещены без блокировки. BlockingQueue без ограничений внутренней емкости всегда сообщает остальную емкость Integer.MAX_VALUE'. Но если вы читаете [здесь] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#put (E)), он четко заявляет, что это не будет блокировать , – Michael

+0

@BobI Это применимо только в том случае, если реализация ограничена по размеру, что является необязательным. 'PriorityBlockingQueue' явно указано как неограниченное. – EJP

4

Согласно Javadoc,

итератора при условии, в методе итератора() не гарантируется траверс элементов приоритетной очереди в любом порядке. Если вам нужно заказать обход, рассмотреть вопрос об использовании Arrays.sort (pq.toArray())

Добавить, быстрый взгляд, опрос и удалить должны работать в приоритетной последовательности, но НЕ итератор.