单对multithreadingJMS生成器

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

然后我使用相同的生成器对象(一个连接但多个会话)并使用线程大小为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号线程运行它们。 这次推送所有3M消息花了大约68秒。

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

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

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

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

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

要回答您的问题,确实需要详细了解特定JMS提供程序。

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

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

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

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

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

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

这就是multithreading在这里以及在其他一些情况下可能会变坏的方式。

————————————–编辑发生的事情:—— ———————————————-

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

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

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

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

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