2012-07-11 127 views
0

在我们的多线程Java应用程序,我们使用的是LinkedBlockingDeque单独的实例为每个线程,线程假设(C1,C2,... C200)LinkedBlockingDeque.take() - 在multipe线程单独的实例

线程T1 & T2接收来自套接字&的数据将对象添加到特定消费者的Q之间的c1到c200之间。

无限循环运行()的内部,它调用LinkedBlockingDeque.take()

在负载运行的javae.exe本身的CPU使用率是40%。当我们总结系统中的其他进程时,整体CPU使用率达到90%。

通过使用JavaVisualVM运行()占用了过多的CPU,我们怀疑LinkedBlockingDeque.take()

像thread.wait因此试图替代品,并通知和的Thread.Sleep(0),但没有改变。

之所以每个消费者具有分离的Q是两个原因, 1.there 2.如果我们转储单Q,所述SEACH时间对所有REQ可能是从T1或T2 消费者C1多于一个的请求c1到c200会更多,并且搜索条件将会延长。 3.and让消费者有单独的Q处理thier请求

设法降低CPU使用率,需要你输入...

SD

回答

0
  1. 做分析和作确保队列方法需要相当多的CPU时间。您的邮件处理过程如此简单,与将队列放入/取出队列相比,处理起来如此简单? 每秒处理多少条消息?有多少个CPU?如果每个CPU每秒处理少于100K条消息,那么很可能原因不是对队列的访问,而是消息处理本身。

  2. 加入LinkedBlockingDeque会创建一个帮助对象的实例。我怀疑,每个新消息都是从堆中分配的,所以每个消息都有2个创建。尝试使用预先分配的消息池和循环缓冲区。

  3. 200线程太多了。这意味着,许多上下文切换。尝试使用actor库和线程池,例如,https://github.com/rfqu/df4j(是的,它是我的)。

  4. 检查http://code.google.com/p/disruptor/是否符合您的需求。

+0

感谢您的回复,我们会根据您的要求处理邮件。最多200条消息/秒。 2个CPU。如果消费者没有消息,则调用LinkedBlockingDeque.take()来阻塞,直到获得消息。 2)该消息包含特定消费者的唯一标识符。对于其他两点,现在还不知道。还没有看到。 – user1517020 2012-07-11 10:46:47

+0

对于如此低的消息速率,调整通信策略不太可能产生任何效果。但是,我会尝试以下变体:单个消息队列,1或2个消费者线程从队列中读取,消费者用方法void processMessage(Message m)表示为对象(不是线程)。消费者线程将消息放入由消息内容选择的消费者对象中。使用2个线程时,需要额外的预防措施不要同时访问同一个消费者对象(演员模型的经典用例):例如每个消费者都有额外的队列。 – 2012-07-11 11:58:11

+0

谢谢。使用单个共享队列,每个消费者将处理数据。这种类型的设计可以达到的最大消息速率是多少。 – user1517020 2012-07-20 12:51:52