这是我在 stackoverflow 上的第一篇文章...我希望有人能帮助我
我的 Java 6 性能大幅下降LinkedBlockingQueue
。
在第一个线程中,我生成一些对象并将其推入队列
在第二个线程中,我将这些对象拉出来。当take()
的方法LinkedBlockingQueue
被频繁调用。
我监控了整个计划take()
方法占用了总体时间最长的时间。
吞吐量从 ~58Mb/s 变为 0.9Mb/s...
使用此类中的静态方法调用队列 pop 和 take 方法
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,或者是否有其他我可以使用的类,当“队列”已满或空时它将阻塞。
亲切的问候
Bart
P.S.:抱歉我的英语不好,我来自德国;)
你的生产者线程很简单放入的元素多于消费者消耗的元素,因此队列最终达到其容量限制,因此生产者等待。
巩固我原来的答案,现在我们基本上有了全貌:
- 您达到了固有的吞吐量限制
LinkedBlockingQueue
(每个队列都有一个)通过极快的速度put()
s,其中甚至连续take()s
,进一步处理为零,无法跟上。 (顺便说一句,这表明在这种结构中,无论如何,在您的 JVM 和机器上,put() 的成本至少比读取稍高一些)。
- 由于消费者锁定了一个特定的锁,因此放置更多的消费者线程可能没有帮助(如果你的消费者实际上正在做一些处理并且限制了吞吐量,那么添加更多的消费者会有所帮助。对于以下场景有更好的队列实现:超过一个消费者(或生产者),你可以尝试
SynchronousQueue
, ConcurrentLinkedQueue
,以及即将到来的TransferQueue
jsr166y)。
一些建议:
- 尝试创建更粗粒度的对象,以便对每个对象进行排队的开销与从生产线程卸载的实际工作相平衡(在您的情况下,似乎您为代表可忽略不计的工作量的对象创建了很多通信开销)
- 您还可以让生产者通过卸载一些消耗性工作来帮助消费者(当有工作要做时,无所事事地等待没有多大意义)。
/在 John W. 正确指出我原来的答案具有误导性后更新
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)