运行Web服务请求的线程池的合理线程数

时间:2009-06-22 18:23:47

标签: java web-services concurrency threadpool

在Java中创建FixedThreadPool Executor对象时,需要传递一个参数,描述Executor可以并发执行的线程数。我正在建立一个服务类,负责处理大量的电话号码。对于每个电话号码,我需要执行Web服务(这是我的瓶颈),然后在hashmap中保存响应。

为了使这个瓶颈对我的服务性能的危害降低,我决定创建一个Worker类来获取未经处理的元素并对其进行处理。 Worker类实现Runnable接口,我使用Executor运行Workers。

可以在同一时间运行的Worker数量取决于Executor FixedThreadPool的大小。 ThreadPool的安全大小是多少?当我用一些大数字作为参数创建FixedTheradPool时会发生什么?

9 个答案:

答案 0 :(得分:8)

可以考虑的事情正在考虑

Runtime.getRuntime().availableProcessors()

给出了一些对系统有意义的线程的方向。

答案 1 :(得分:6)

如果每个工作线程都需要进行Web服务调用,那么池中的线程数应该受到Web服务可以处理的同时请求数量的强烈影响。除此之外的任何其他线程都不会淹没Web服务。

答案 2 :(得分:2)

我已经读过某个地方,最佳线程数是核心数* 25.似乎.NET使用它作为ThreadPool的默认值。但是,如果您有大量的Web服务调用,则最好使用单个线程并检查响应的Web服务调用列表。当响应到达时,只需处理该条目并将其从列表中删除。

答案 3 :(得分:2)

如果您具有对Web服务的访问权限,请考虑创建批处理功能以在一次通话中检查多个电话号码。

在较新的.NET中,有一个ThreadPool可以根据自己的性能配置文件进行扩展和缩小。不幸的是,Java的版本要么是固定的,要么根据传入的工作增长到极限。

我们曾经有类似的担忧。我们的解决方案是允许客户调整池大小并随意调整性能。

I / O操作池大小可以考虑一些网络和数据属性:网络带宽,消息大小,Web服务的处理时间和样式,本地核心数。

答案 4 :(得分:2)

如果每个计算等同于对Web服务的调用,那么您应该考虑您对该服务的负载量/服务将允许或允许服务所有者允许的并发连接数。大多数可公开访问的服务一次只能期望来自任何单个用户的这种连接。如果可能,请联系服务所有者以了解其使用政策。此类连接的数量将决定您可以使用的线程数。

答案 5 :(得分:1)

让我们假设Web服务具有无限可扩展性,并且没有人会关心您是否通过请求向其发送垃圾邮件。我们还假设Web服务响应在1秒范围内,而本地处理时间是5毫秒。

当您拥有与处理核心相同数量的忙线程时,吞吐量最大化。

在这些假设下,对于任何理智的线程池大小,您都无法在多核处理器上最大化吞吐量。要实现每秒最大事务数,您必须断开每个连接模型的线程。查找前面提到的非阻塞I / O(NIO)或异步完成令牌模式的Java实现(Windows中的IO完成)。

请注意,为每个创建的线程保留的堆栈内存实际上只是保留的地址空间,而不是实际分配或提交的内存。随着堆栈尝试增长异常被抛出,这导致堆栈内存按需提交。结果是它只与32位内存管理器真正相关。对于64位内存,即使您只使用物理内存支持该空间的一小部分,也会有一个巨大的地址空间。至少,这就是我理解Windows的工作方式,我不确定Unix世界。

答案 6 :(得分:0)

不要忘记,您创建的每个线程也会对内存的堆栈大小提出要求。因此,创建一个线程池将影响进程的内存占用(请注意,某些池在实际需要之前不会创建线程,因此在启动时您将看不到任何内存增加)。

此堆栈大小可通过-Xss配置(类似于-Xmx等)。我相信每个线程的默认值是512Kb。目前我找不到任何权威的确认。

答案 7 :(得分:0)

我想知道你是否会更好地使用NIO而不是线程,因为你的限制因素是web服务器+网络瓶颈,而不是客户端CPU。

否则,最多不应超过Web服务可以支持的并发连接数。

答案 8 :(得分:0)

如果您对并行数组操作进行繁重的计算,那么经验法则是拥有处理器数量的线程数。