如何确定高延迟网络请求的最佳线程数?
我正在编写一个实用程序,该实用程序必须发出数千个网络请求。每个请求仅收到一个小数据包作为响应(类似于 ping),但可能需要几秒钟才能完成。处理每个响应在一行(简单)代码中完成。
这样做的最终效果是,计算机不受 IO 限制、文件系统绑定或 CPU 绑定,它仅受响应延迟的约束。
这与有一种方法可以确定理想的线程数?和Java确定最佳线程数的最佳方法[重复]类似,但不相同。主要区别在于我只受延迟的约束。
我正在使用一个对象来运行线程,并使用一个对象来跟踪需要检索结果的线程:ExecutorService
Queue<Future<Integer>>
ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
Queue<Future<Integer>> futures = new LinkedList<Future<Integer>>();
for (int quad3 = 0 ; quad3 < 256 ; ++quad3) {
for (int quad4 = 0 ; quad4 < 256 ; ++quad4) {
byte[] quads = { quad1, quad2, (byte)quad3, (byte)quad4 };
futures.add(executorService.submit(new RetrieverCallable(quads)));
}
}
...然后,我将队列中的所有元素排出队列,并将结果放在所需的数据结构中:
int[] result = int[65536]
while(!futures.isEmpty()) {
try {
results[i] = futures.remove().get();
} catch (Exception e) {
addresses[i] = -1;
}
}
我的第一个问题是:这是跟踪所有线程的合理方法吗?如果线程 X 需要一段时间才能完成,则许多其他线程可能会在 X 完成之前完成。线程池是否会在等待空插槽时耗尽自身,或者对象是否会以这样一种方式管理池,即已完成但尚未处理的线程将移出可用插槽,以便其他线程开始?ExecutorService
我的第二个问题是,我可以使用什么准则来查找进行这些调用的最佳线程数?我甚至不知道这里的数量级指导。我知道它与256个线程一起工作得很好,但对于1024个线程,它似乎花费了大致相同的总时间。CPU利用率徘徊在5%左右,因此这似乎不是问题。有这么多的线程,我应该查看哪些指标来比较不同的数字?显然,处理批处理的总时间,每个线程的平均时间...还有什么?内存在这里是一个问题吗?