Java:非阻塞队列上的最大 CPU 等待

标签 java concurrency

我有以下代码:

public void run() {
    while (true) {
        m = q.poll();
        if (m != null) {
            kf.sendMessage(m.topic, m.message);
        }
    }
}

其中 q 是一个 ConcurrentLinkedQueue。目前这占用了我 100% 的 CPU。有没有更有效的方法来等待非阻塞队列?我更喜欢使用非阻塞队列,因为我期待队列中生产者的突发流量,所以我想最大化性能。如果 q.poll() 返回 null,有没有办法放弃我的线程对 cpu 的控制?

我可以选择切换到阻塞队列,但我很好奇这样做的正确方法是什么。

编辑 - 很多好的回复!感谢你的帮助。现在我将只切换到 linkedblockqueue,如果我开始遇到性能问题,请重新评估。

最佳答案

如果你无事可做,只想等待(不使用 CPU)直到数据可用,那么使用阻塞队列。这正是它的用途,使用类似 take 的方法:

Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), waiting if necessary until an element becomes available.

如果您对它的实现方式感兴趣,可以查看 the source对于这些类,例如 LinkedBlockingQueue#take:

public E take() throws InterruptedException {
    E x;
    int c = -1;
    final AtomicInteger count = this.count;
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lockInterruptibly();
    try {
        while (count.get() == 0) {
            notEmpty.await();
        }
        x = dequeue();
        c = count.getAndDecrement();
        if (c > 1)
            notEmpty.signal();
    } finally {
        takeLock.unlock();
    }
    if (c == capacity)
        signalNotFull();
    return x;
}

如您所见,他们维护了几个 Conditions发出队列是否为空的信号。

关于Java:非阻塞队列上的最大 CPU 等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23376822/

相关文章:

java - spring boot删除 Controller 中的员工代码困惑

java - 无法访问类的属性

java - 限制迭代时删除元素

java - 在 jar 中运行类时从 jar 中获取所有 .class

java - 线程同步相关问题

java - 如何限制任务,以便一次只运行一个任务并忽略其余任务

java - Java 1.4 中 Lock.tryLock() 的替代方案

java - JPA 多线程 org.eclipse.persistence.exceptions.ConcurrencyException

java - 在 Java Swing GUI 中让线程不断运行和更新文本框的最佳方法是什么

java - 使用 JPA 1.0 的 CriteriaQuery