【发布时间】:2013-01-01 08:31:18
【问题描述】:
我有一个多线程程序,它的线程数可以自定义。该程序负责生成 HTTP 请求,将请求发送到 Web 服务,接收响应并解析响应以获取一些结果值。
由于每个请求几乎需要 1 秒才能获得响应,为了让程序获得尽可能多的响应,启动了多个线程。
以下代码用于启动多线程:
...
for (int i = 0; i < threadNum; i++) {
threadArray[i] = new Thread(requestGeneratorArray[i]);
threadArray[i].start();
}
for (int i = 0; i < threadNum; i++) {
try {
threadArray[i].join();
} catch (InterruptedException e) {
logger.error(e);
}
}
...
当线程数为50,一共产生并发送10K个请求时,程序运行良好。当线程数仍为50,总请求数为100K时。当发送 95K+ 请求时,程序挂起。也不例外,程序就挂在那里。
然后我添加一些像这样的 JVM 参数:java -Xmx1024M -Xms512M -XX:MaxPermSize=256m ... 使用这些参数,50 个线程/100K 请求有效。但是,50 个线程/1M 请求再次挂起。我将线程数设置为20,请求数设置为1M,它又工作了。
我想将线程数设置为 50,因为在使用较少请求数 (10K) 的情况下进行测试,50 个线程的效率最高。请求数可能比 10M、100M、事件 1B 大得多。在这种情况下,增加 -Xmx -Xms 或 MaxPermSize 的大小不是一个好主意。我该怎么办?程序挂起的根本原因是什么?
================================================ =============
我直接使用了 Executor Service 而不是线程。但是问题也出现了。我重新检查了代码,发现有一个错误:我为每个请求实例化了一个 HttpClient 对象。我将代码更改为为每个线程实例化一个 HttpClient 实例,并且程序不再挂起。
我认为程序挂起的根本原因是它与 Web 服务建立了太多的 HTTP 连接,并且耗尽了 Web 服务的所有线程。这使得 Web 服务无法响应任何新到达的请求。这是正确的吗?
【问题讨论】:
-
“待定”是什么意思?是挂的意思吗?有很多事情可能会影响到这一点,尤其是您要连接的网络服务器可能有最大数量的并发连接,这意味着您程序中的大多数线程都在等待网络服务器开始与它们对话。跨度>
-
您可以通过使用内置线程池(例如Executors factory 提供的线程池之一)来让您的生活更轻松,而不是自己管理一个(但它可能无法解决您的问题)。
-
如何发送请求?有多少线程在发送,有多少线程在解析请求?
-
如果您希望您的应用程序扩展到任意 #/requests,也许您可能希望考虑使用 [线程池](docs.oracle.com/javase/tutorial/essential/concurrency/…),而不是为每个请求生成一个新线程。恕我直言...
-
@JohnFarrelly:是的,它应该是“挂起”而不是“待定”。我已与网络服务开发人员确认并确保没有连接限制。
标签: java multithreading