我有以下代码:
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/