使用迭代器移除并插入到LinkedHashMap中



我知道在迭代期间编辑HashMap或LinkedHashMap内容而不引发ConcurrentModificationException是不可能的。然而,我有一种情况,我需要应用它。我正在写一个虚拟内存模拟使用时钟实现的第二次机会算法。注意:RAM是一个LinkedHashMap,因此迭代顺序遵循插入顺序。这是我目前的方法(tmp、hand和entry是在主循环逻辑之外声明的变量:

PTE tmp; // A tmp PageTableEntry reference used for shuffling PTEs across RAM and the Page Table
Iterator<Entry<Integer, PTE>> hand; // Iterator that represents the clock hand
Map.Entry<Integer, PTE> entry = null; // A tmp Map Entry ref that is used to store the return of the hand Iterator

hand = RAM.entrySet().iterator(); // Set the Clock hand to the oldest PTE in RAM
entry = hand.next(); // Advance the iterator to the first RAM entry
tmp = entry.getValue(); // Get the PTE the Clock hand is pointing at
while (tmp.ref && hand.hasNext()) { // Advance the clock hand through RAM until finding an unreferenced PTE
debugPrint(String.format("while:The hand is pointing at page # %d, ref == %bn", tmp.baseAddr, tmp.ref), 1);
tmp.ref = false; // Set the ref bit to false to give the PTE a second chance
entry = hand.next(); // Select next PTE in RAM
tmp = entry.getValue();
}
if (tmp.ref && !hand.hasNext()) { // Corner Case: The clock hand has found all PTEs in RAM to be referenced, must follow FIFO
debugPrint(String.format("!HasNext:The hand is pointing at page # %d, ref == %bn", tmp.baseAddr, tmp.ref), 1);
tmp.ref = false; // Marked for eviction, must be set to unreferenced
hand = RAM.entrySet().iterator(); // Reset the clock hand to point back to the first PTE inserted.
entry = hand.next();
tmp = entry.getValue();
}

这产生了几乎正确的输出,但我的问题是不应该在每次使用算法时重新创建迭代器。我需要一种方法来存储迭代器将要指向的下一个元素,这样我就可以从LinkedHashMap中删除tmp,并将其替换为新的PageTableEntry,这样下次迭代器运行时,它就会从停止的地方恢复,直到它到达末尾时才能看到新添加的条目,并且必须循环回来。

Iterator接口没有API来向其添加元素并防止并发修改是其目标之一,因此除非您编写自己的LinkedHashMap实现,否则优化非常困难。

我看不到映射的密钥有任何用法,所以如果LinkedHashMap可以更改,那么你可以通过使用队列来避免这种复杂性。如果你一直想要顺序处理,或者如果你有一些查找,也可以使用优先级队列

最新更新