单对多线程JMS生成器

时间:2014-09-14 10:07:52

标签: java multithreading jms

我想知道使用多线程生产者而不是单线程生成器会产生多大的时差。我在我的本地机器上设置了一个ActiveMQ,编写了一个生成器类,它将在其构造函数中初始化并启动JMS连接。我将消息限制设置为3M,将所有消息推送到ActiveMQ大约需要50秒。我发了一个字符串"你好世界" 3M次。

然后我使用相同的生成器对象(一个连接但多个会话)并使用线程大小为8的ExecutorService运行它。在run方法中,我将3M除以8只是为了确保每个线程发送的消息不超过375000条。在这种情况下,推送所有消息大约需要60秒。

ExecutorService service = Executors.newFixedThreadPool(8);

    for (int i = 0; i < 8; i++) {

        service.execute(producer);
    }

然后我创建了8个生成器,每个生成器都有自己的连接,并使用ExecutorService或8号线程运行它们。这次需要大约68秒来推送所有3M消息。

for (int i = 0; i < 8; i++) {
        service.execute(new Producer());
    }

我想知道,为什么单线程生产商会在这里表现更好?我将每个场景运行了大约10次,但结果保持不变。

6 个答案:

答案 0 :(得分:1)

与Broker的连接使用单个TCP / IP连接来通过线路推送每条消息。在大多数情况下,在同一连接上写入生产者的多个线程没有任何好处,因为当它们通过JMS层进入有线协议层时,所有调用将变为串行。在您的情况下,由于线程调度加上锁争用加上管理线程池的开销,需要更长的时间。

另一件需要考虑的事情是,根据您的生产者和发送到消息的目的地将同步发送到代理,生产者将阻止等待代理确认消息已存储并赢得&# 39;迷路这会产生很大的开销,但需要保证消息传递。即使您使用多个连接,所有这些连接的吞吐量也会受到代理运行的磁盘速度的限制,因为它必须首先写入所有持久性消息。

尝试优化代码确实超出了StackOverflow的范围,您需要做一些研究并了解JMS代理的体系结构的含义以及您使用的代理的调优功能。如果您的线程为每条消息打开一个新连接,那么这将是一个巨大的性能损失,因为建立新连接是一项昂贵的操作,因此我建议您查看JMS连接池,以此作为提高客户端性能的方法。 / p>

对于您的情况,您可以查看异步发送或在事务中发送批量消息,以减少每次发送所花费的时间。

答案 1 :(得分:1)

由于一些原因,多线程可能比线程慢。一个是计算机的CPU是有限数字,因此不能同时运行所有线程使其变慢。另一个原因是你也有一个有限的内存量导​​致线程需要更长的时间,因为它需要更多的内存。

以这种方式考虑多线程,你有一个可以最佳地适合3个走廊的走廊。如果你的人数较少,那么人们需要更长时间才能让所有人通过它。另外,如果你试图让太多的人立刻穿过它走廊来堵塞,那么任何人都很难通过它。

这就是多线程在这里以及在其他一些情况下可能会变坏的原因。

--------------------------------------编辑发生了什么: -------------------------------------------------- -

你在问题​​中说过你将单线程程序将3M除以8,这样它就不会发送超过375000条消息。但是当你多线程时,你发送的所有3M而不是375000?如果这是真的,那么多线程比单线程慢的原因是因为java不能在同一时间执行不同的线程,看起来它因为它的运行速度而同时执行,但它确实是在您设置的所有线程之间切换。它需要花一点时间在它之间切换。几纳秒,因此需要更长的时间,因为即使多线程中的每个线程在单个线程中运行相同的数量,它也需要在线程之间切换,这使得它花费的时间非常少,从而加起来8运行所需的额外秒数。

答案 2 :(得分:1)

从JMS应用程序的角度来看,您已将应用程序编写为多线程;多个会话,每个会话都有自己的JMS生成器对象,由不同的线程驱动。假设您的应用程序没有对诸如锁等资源的争用,那就是好的。

就发送消息的效率而言,取决于客户端和服务器端部件如何有效地实现JMS提供程序。 JMS实现中是否存在锁定或争用?也许它试图通过同一个套接字发送所有内容 - 在这种情况下存在争用。或许还有一些其他锁。

可能在底层队列数据结构服务器端有一个锁服务器端。

要回答您的问题,确实需要具体JMS提供商的详细知识。

答案 3 :(得分:1)

我猜测管理多个会话的开销,他们与单一连接访问的同步以及线程切换可能是原因。

为什么在发送端使用多个线程时它应该更快?该行只有一个和最大数量的线程,我认为潜在的性能增益是两个 - 当第一个发送数据时,第二个正在准备它的数据并且它们交替切换。

答案 4 :(得分:0)

我的钱是在Calanais概念上。您是否尝试在应用程序运行时对其进行监控?像VisualVM这样的简单工具可以帮助您找出花费的时间。

答案 5 :(得分:0)

你注意到的差异非常小,但我认为多线程处理器花费的时间更多,因为线程之间的cpu资源的并发性。多线程处理器需要在线程之间共享cpu,这可能会花费时间和额外处理,有时会使您的进程变得更慢。虽然单线程处理器不需要在没有其他线程的情况下共享cpu,但它可以更有效地运行。另一方面涉及用于每个线程的资源。它们只在内存中使用字符串,不能访问其他资源,如磁盘文件或数据库或tcp端口。在这种情况下,我认为,单线程进程将比多线程进程更快。