java - 使用 ConcurrentSkipListMap 实现的优先级队列,不确定如何让消费者阻塞它

标签 java multithreading priority-queue

我有一个使用 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/

相关文章:

Java deleteOnExit 和 addShutdownHook - 哪个先出现?

java - 通过反射检查局部变量值的变化

c++ - 在另一个线程中使用线程 vector : error attempting to reference a deleted function

C++ 线程/vector 聊天

c++ - 优先级队列中自定义比较器的访问冲突

java - 使用 Spring Boot @WebMvcTest 进行测试时如何从我的上下文中排除其他 @Controller

c# - 仅使用一小部分 CPU 在多个任务中运行 CPU 密集型方法?

java - 如何解决错误 : 15: error: cannot infer type arguments for PriorityQueue<> in openjdk 1. 7.0_95?

C++ priority_queue 自定义比较器和删除任何项目

java - 如何使用 void set 方法在静态常量帮助程序类中创建对象?