Я пишу утилиту, которая должна делать тысячи сетевых запросов. Каждый запрос получает только один небольшой пакет в ответ (аналогично ping), но может занять несколько секунд для завершения. Обработка каждого ответа завершается в одной (простой) строке кода.
Чистый эффект этого заключается в том, что компьютер не привязан к IO, привязан к файловой системе или связан с ЦП, он связан только с задержкой ответов.
Это похоже на, но не то же самое, что Есть ли способ определить идеальное количество потоков? и Java лучший способ определить оптимальное количество потоков [duplicate]... Основное различие заключается в том, что я связан только с задержкой.
Я использую объект 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 потоками. Загрузка процессора колеблется около 5%, так что это не проблема. С этим большим количеством потоков, каковы все показатели, на которые я должен смотреть, сравнивать разные числа? Очевидно, общее время для обработки партии, среднее время на поток... что еще? Здесь проблема памяти?