我已经实现了从头部提取项目的例程,更新它的优先级并使用非阻塞方法将其放回队列(使用AtomicReference)
def head(): Entry = {
def takeAndUpdate(e: Entry, success: Boolean): Entry = {
if (success) {
return e
}
val oldQueue = queueReference.get()
val newQueue = oldQueue.clone()
val item = newQueue.dequeue().increase()
newQueue += item
takeAndUpdate(item.e, queueReference.compareAndSet(oldQueue, newQueue))
}
takeAndUpdate(null, false)
}
现在我需要找出队列中的任意Entry,更改它的优先级并将其放回队列。似乎PriorityQueue不支持这个,所以我应该使用哪个类来实现所需的行为?
有关答案 0 :(得分:2)
使用不可变树图(immutable.TreeMap
)来完成此任务。您必须以某种方式找到您想要的条目 - 最好的方法是将您使用的信息部分(Key
)与要查找带有密钥的条目以及您希望返回的实际条目相关联地图中的值(调用此Entry
)。
使用queueReference
重命名treeReference
。在您创建集合的代码部分中,使用immutable.TreeMap[Key, Entry](<list of elements>)
。
然后像这样修改代码:
def updateKey(k: Key) {
@annotation.tailrec def update(): (Key, Entry) = {
val oldTree = treeReference.get()
val entry = oldTree(k)
val newPair = modifyHoweverYouWish(k, entry)
val newTree = (oldTree - k) + newPair
if (treeReference.compareAndSet(oldTree, newTree)) newPair
else update()
}
update()
}
如果compareAndSet
失败,您必须像在资源中那样重复。最好使用@tailrec
,如上所示,以确保函数是尾递归并防止潜在的堆栈溢出。
或者,您可以使用immutable.TreeSet
- 如果您知道对Entry
对象的确切引用,则可以使用它来通过-
删除元素,然后添加它在致电increase()
后回来。代码几乎相同。