Java 优先级队列中的并发修改异常

Java concurrentmodificationexception in priority queue

我在迭代我的优先级队列时遇到问题,这会导致 Concurrentmodificationexception。

迭代代码:

Queue<Patient> pq = new PriorityQueue<Patient>();
 Iterator<Patient> it = pq.iterator();    
            while(iter.hasNext()){
                Patient current = iter.next();
                if(current.getName().equals(patientName)){

                    pq.remove(p);
                    }


                } 

有错误说 iter.next() 消耗了 Concurrentmodificationexception。 我可以知道如何解决这个问题吗?我已经在互联网上搜索了,但仍然找不到解决方法。

尝试使用 ConcurrentLinkedQueue 而不是 PriorityQueue

根据:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html

Beware that, unlike in most collections, the size method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires a traversal of the elements, and so may report inaccurate results if this collection is modified during traversal.

将您的代码更改为以下以解决它 -

Queue<Patient> pq = new PriorityQueue<Patient>();
 Iterator<Patient> iter = pq.iterator();    
            while(iter.hasNext()){
                Patient current = iter.next();
                if(current.getName().equals(patientName)){

                    iter.remove();
                    }


                } 

说明 ConcurrentModificationException 是从迭代器的 next() 方法抛出的,如果底层集合(在你的例子中是队列)即任何元素有任何结构变化直接在队列中添加或删除。它被称为Fail Fast Iterator

自 Java8 起,您可以删除使用 removeIf,它是 Collection 合同的一部分。

鉴于 removeIf 方法采用谓词,您的代码可以像这样简单:

priorityQueue.removeIf(patient -> patient.getName().equals(patientName));

至于您遇到的并发异常,这只是因为您试图在已经迭代时直接删除 PriorityQueue#remove 调用,这会使迭代器过时。迭代时删除的正确方法是使用 Iterator#next,然后使用 Iterator#remove(这实际上是 removeIf 的默认实现)。