首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LinkedBlockingQueue .take()性能

LinkedBlockingQueue .take()性能
EN

Stack Overflow用户
提问于 2013-06-19 22:24:03
回答 2查看 1.7K关注 0票数 0

我使用的是由多个线程填充的LinkedBlockingQueue,项目的数量很大(数千万个对象)。

LinkedBlockingQueue.take()需要花费很多时间(通过分析器检查)-- 56%的时间。

队列从不为空!!

什么会影响take()方法的性能?

更新:我对处理take()结果的代码做了一些修改,我还将take()放到了另一个线程中,性能几乎提高了50%。

我不明白这怎么可能,因为我没有改变推杆的任何逻辑……

更新:

在调用take()之前,我已经计算了队列已满的次数:

使用原始代码时,90%的呼叫队列已满。

使用改进的代码,13%的呼叫队列已满。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-19 22:29:48

如果我们查看代码here,我们可以看到在获取元素之前必须获取一个锁。如果有很多线程在占用,那么这个锁上就会有争用--这些线程不是在等待什么东西出现,而是在等待其他线程占用东西。

代码语言:javascript
复制
 public E take() throws InterruptedException {
        E x;
        int c = -1;
        final AtomicInteger count = this.count;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lockInterruptibly();
        try {
            try {
                while (count.get() == 0)
                    notEmpty.await();
            } catch (InterruptedException ie) {
                notEmpty.signal(); // propagate to a non-interrupted thread
                throw ie;
            }

            x = extract();
            c = count.getAndDecrement();
            if (c > 1)
                notEmpty.signal();
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }

编辑

在你有一个击球手和许多推杆的情况下,队列不断变满,瓶颈将变成signalNotFull(),如下面的代码所示

代码语言:javascript
复制
private void signalNotFull() {
    final ReentrantLock putLock = this.putLock;
    putLock.lock();
    try {
        notFull.signal();
    } finally {
        putLock.unlock();
    }
}

这需要使用putLock来通知队列中现在有空间的事实。

票数 5
EN

Stack Overflow用户

发布于 2013-06-19 22:29:24

take()是相当轻量级的,但是如果你足够调用它,它将消耗大量的CPU。这听起来像是你在传递大量的对象,而这些对象对于消费者来说只需要很少的工作。我建议尝试重组你的问题,这样做会更有效率。

例如,您可以:

  • 使用专为此类问题设计的中断程序。
  • 发送块/批数据,例如对象列表,而不是许多单个对象。
  • 使用多个交换器(适用于少数编写器)如果您的目标是保留数据,则
  • 使用类似历史记录的内容。

也有可能你的个人资料并不完全准确。当你测量一小段时间时,它可能会给出混合的结果。

顺便说一下: take()是单线程的。如果有许多线程试图同时调用take(),它们将会相互阻塞。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17193840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档