我有一个可以自定义线程号的多线程程序。该程序负责生成 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 服务无法响应任何新到达的请求。这是对的吗?