Java 8中的PriorityBlockingQueue流无序

jac*_*684 5 java priority-queue java-8 java-stream

这两段代码具有不同的输出顺序.第一件:

while(!jobQueue.isEmpty()) {
    TimeoutJobRequest job = jobQueue.peek();
    if(job.isReady()) {
        execute(job);
        jobQueue.poll();
    } else {
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

第二件:

jobQueue.stream()
        .filter(TimeoutJobRequest::isReady)
        .peek(jobQueue::remove)
        .forEach(this::execute);
Run Code Online (Sandbox Code Playgroud)

请注意,这jobQueue是一个PriorityBlockingQueue.

重新排序仅在this::execute相对较长时(例如几秒钟)发生.

Hel*_*ira 7

所述stream的PriorityBlockingQueue跟随Iterator其中根据顺序,文档:

方法iterator()中提供的迭代器不保证以任何特定顺序遍历PriorityBlockingQueue的元素.

如果您想要优先顺序,则需要来自poll的元素PriorityBlockingQueue.

PriorityBlockingQueue<Integer> pq = new PriorityBlockingQueue<>();
pq.add(5);
pq.add(8);
pq.add(3);

System.out.println("-- Try 1 --");
pq.stream().forEach(System.out::println);

System.out.println("-- Try 2 --");
IntStream.range(0, pq.size()).map(i -> pq.poll()).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

输出(可能取决于Java实现):

-- Try 1 --
3
8
5
-- Try 2 --
3
5
8
Run Code Online (Sandbox Code Playgroud)


Mar*_*ról 5

如果您想创建遵循队列顺序的流,您可以尝试以下代码(它会清空队列):

Stream.generate(jobQueue::poll).limit(jobQueue.size())
Run Code Online (Sandbox Code Playgroud)