我有一个使用 ConcurrentSkipListMap 实现的优先级队列,使用 16 个不同的优先级。
class ConcurrentPriorityQueue {
ConcurrentSkipListMap<Long, Message> queue = new ConcurrentSkipListMap<>();
AtomicLong counter16 = new AtomicLong(Long.MAX_VALUE);
AtomicLong counter15 = new AtomicLong(Long.MAX_VALUE / 8 * 7);
AtomicLong counter14 = new AtomicLong(Long.MAX_VALUE / 4 * 3);
// etc
AtomicLong counter1 = new AtomicLong(Long.MIN_VALUE / 8 * 7);
void addPriority16(Message message) {
queue.put(counter16.getAndDecrement(), message);
}
void addPriority15(Message message) {
queue.put(counter15.getAndDecrement(), message);
}
// and so on
}
这并不完全是类的组织方式(例如,我将 AtomicLongs 放在数组中),但我认为这段代码会更清晰。还有一个 DelayQueue 可以删除旧消息或提高旧消息的优先级(取决于消息类型)。
我的问题是,我有几个消费者正在使用 pollLastEntry()
为了从队列中删除最高优先级的消息,然后在队列为空时 hibernate ,但问题是队列 Activity 会突发 - 它会持续一个小时而不包含多个消息,然后在接下来的一个小时内它永远不会空。因此,我想使用阻塞方法从队列中删除消息,这样我就不会在重复 hibernate 的线程上浪费资源(当 Activity 较少时,我会使用指数退避让它们 hibernate 更长时间,但这会使它们在队列再次启动时失去响应),但不清楚实现此目的的最佳方法 - 我有丰富的使用阻塞队列的经验,但实现它们的经验为零。我的第一个想法是在 hibernate 的消费者中实现指数退避,然后在队列 Activity 再次启动时中断它们,但我首先想看看是否有更好的方法来做到这一点。
最佳答案
我会实现一个包装器
class Wrapper implements Comparable<Wrapper> {
long priority;
Message message;
Wrapper(long priority, Message message) {
this.priority = priority;
this.message = message;
}
@Override
public int compareTo(Wrapper w) {
return Long.compare(priority, w.priority);
}
}
并使用 PriorityBlockingQueue 而不是 ConcurrentSkipListMap
关于java - 使用 ConcurrentSkipListMap 实现的优先级队列,不确定如何让消费者阻塞它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16454262/