LinkedBlockingQueue的Java性能问题 [英] Java performance problem with LinkedBlockingQueue

查看:400
本文介绍了LinkedBlockingQueue的Java性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在stackoverflow上的第一篇文章...我希望有人可以帮助我

this is my first post on stackoverflow... I hope someone can help me

我在Java 6中有很大的性能回归 LinkedBlockingQueue
在第一个线程中,我生成一些对象,我将其推入队列
在第二个线程中,我将这些对象拉出来。当频繁调用 LinkedBlockingQueue take()方法时,会发生性能回归。
我监控了整个程序,而 take()方法总体上占据了最多的时间。
并且吞吐量从~58Mb / s到0.9Mb / s ...

I have a big performance regression with Java 6 LinkedBlockingQueue. In the first thread i generate some objects which i push in to the queue In the second thread i pull these objects out. The performance regression occurs when the take() method of the LinkedBlockingQueue is called frequently. I monitored the whole program and the take() method claimed the most time overall. And the throughput goes from ~58Mb/s to 0.9Mb/s...

队列弹出并使用静态方法调用方法ar class

the queue pop and take methods ar called with a static method from this class

public class C_myMessageQueue {

    private static final LinkedBlockingQueue<C_myMessageObject> x_queue = new LinkedBlockingQueue<C_myMessageObject>( 50000 );

    /**
     * @param message
     * @throws InterruptedException
     * @throws NullPointerException
     */
    public static void addMyMessage( C_myMessageObject message )
            throws InterruptedException, NullPointerException {
        x_queue.put( message );
    }

    /**
     * @return Die erste message der MesseageQueue
     * @throws InterruptedException
     */
    public static C_myMessageObject getMyMessage() throws InterruptedException {
        return x_queue.take();
    }
}

如何调整 take()方法完成至少25Mb / s,或者是否有一个我可以使用的类,它将在队列满或空时阻塞。

how can I tune the take() method to accomplish at least 25Mb/s, or is there a other class I can use which will block when the "queue" is full or empty.

亲切的问候

Bart

PS:抱歉我的英语不好,我来自德国;)

P.S.: sorry for my bad english, I'm from Germany ;)

推荐答案

你的制作人主题简单放置的元素多于消费者消费,因此队列最终达到其容量限制,因此生产者等待。

Your producer thread simply puts more elements than the consumer consumes, so the queue eventually hits its capacity limit, thus the producer waits.

巩固我的原始答案,因为现在我们基本上已经全面了解:

Consolidating my original answer since now we have basically the full picture:


  • 您通过执行非常快的 put() s来达到 LinkedBlockingQueue (每个队列都有一个)的固有吞吐量限制,即使连续 take()s ,零进一步处理,也无法跟上。 (顺便说一下,这表明在这个结构中,无论如何,在你的JVM和机器上,put()s至少比读取的成本稍高一些)。

  • 由于存在消费者锁定的特定锁定,因此放置更多消费者线程可能无法提供帮助(如果您的消费者实际上正在进行某些处理并且限制了吞吐量,那么添加更多消费者将会对于具有多个消费者(或生产者)的方案,有更好的队列实现,您可以尝试 SynchronousQueue ConcurrentLinkedQueue ,以及jsr166y的即将到来的 TransferQueue

  • You hit the inherent throughput limit of the LinkedBlockingQueue (every queue has one) by doing extremely fast put()s, where even continual take()s, with zero further processing, cannot keep up. (By the way this shows that in this structure, on your JVM and machine anyway, put()s are at least slightly more costly than the reads).
  • Since there is a particular lock that consumers lock, putting more consumer threads could not possibly help (if your consumer was actually doing some processing and that was bounding the throughput, then adding more consumers would help. There are better queue implementations for a scenario with more than one consumers (or producers), you could try SynchronousQueue, ConcurrentLinkedQueue, and the upcoming TransferQueue of jsr166y).

一些建议:


  • 尝试制作更粗粒度的对象,以便排队每个对象的开销与从生产中卸载的实际工作进行平衡线程(在您的情况下,似乎您为代表可忽略不计的工作量的对象创建了很多通信开销)。

  • 您也可以让生产者通过卸载一些消耗工作来帮助消费者(不多在有工作要做的时候,等待空闲ne)。

/在John W.正确指出我的原始答案误导后更新

/updated after John W. rightly pointed out my original answer was misleading

这篇关于LinkedBlockingQueue的Java性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆